下面是一个REPL会话的样本,表明定义一个返回包含字节的`clojure.core.Vec`对象的数据读取器的方法,并使用REPL中的调用来说明它是此类型。
如果您能分享一个类似的REPL会话,其中您尝试的东西给您预期的结果为clojure.core.Vec
,而当您希望它是clojure.lang.PersistentVector
时,您可以在后续评论中分享它们,这可能会帮助我们确定正在发生什么。
$ clojure
Clojure 1.10.1
user=> (defn first-non-hex-char [string]
(re-find #"[^0-9a-fA-F]" string))
#'user/first-non-hex-char
user=> (defn hex-string-to-clojure-core-vec-of-byte [hex-string]
(if-let [bad-hex-digit-string (first-non-hex-char hex-string)]
(throw (ex-info (format "String that should consist of only hexadecimal digits contained: %s (UTF-16 code point %d)"
bad-hex-digit-string
(int (first bad-hex-digit-string)))
{:input-string hex-string
:bad-hex-digit-string bad-hex-digit-string}))
(if (not (zero? (mod (count hex-string) 2)))
(throw (ex-info (format "String contains odd number %d of hex digits. Should be even number of digits."
(count hex-string))
{:input-string hex-string
:length (count hex-string)}))
;; There are likely more efficient ways to do this, if
;; performance is critical for you. I have done no performance
;; benchmarking on this code. This code is taking advantage of
;; JVM library calls ready aware of.
(let [hex-digit-pairs (re-seq #"[0-9a-fA-F]{2}" hex-string)
byte-list (map (fn [two-hex-digit-str]
(.byteValue
(java.lang.Short/valueOf two-hex-digit-str 16)))
hex-digit-pairs)]
(apply vector-of :byte byte-list)))))
#'user/hex-string-to-clojure-core-vec-of-byte
user=> (def bv1
(binding [*data-readers*
(assoc *data-readers*
'my.ns/byte-vec user/hex-string-to-clojure-core-vec-of-byte)]
(read-string "#my.ns/byte-vec \"0123456789abcdef007f80ff\"")))
#'user/bv1
user=> bv1
[1 35 69 103 -119 -85 -51 -17 0 127 -128 -1]
user=> (type bv1)
clojure.core.Vec
user=> (type (bv1 0))
java.lang.Byte