在Clojure中将字节转换为字符串

3
我是一名能翻译文本的有用助手。
我正在将Clojure中的字节数组转换为字符串,并且遇到了一个奇怪的问题,我不知道原因。
字节数组定义如下:
(def a (byte-array  (byte 72) (byte 105)))

当我将它转换成向量时,它会显示。
(vec a)

输出结果为(105, 105, 105, ......68次...., 105)的数组。

这个输出结果是一个包含72个元素的105数组。为什么会这样呢?我试图将一个字节数组转换成字符串并使用了

(String. (byte-array (byte 72) (byte 105)))

循环嵌套72次的操作会输出72个i。另一方面,当我执行

的操作时,会触发一个语法错误。
(map char [(byte 72) (byte 105)])

我得到了输出H和I。因此,我正在尝试将字节数组转换为向量。如果有其他方法,请告诉我。

2个回答

8
你正在调用带有两个参数的函数版本,因此你的第一个参数设置要创建的数组的大小,而第二个参数不是序列,因此被视为init-val;请参见:
user=> (doc byte-array)
-------------------------
clojure.core/byte-array
([size-or-seq] [size init-val-or-seq])
  Creates an array of bytes

此外,初始值是从一个“序列”(如参数名称所示)中获取的。因此,您可以执行以下操作:

user=> (String. (byte-array [(byte 72) (byte 105)]))
"Hi"

1

@cfrick已经回答了如何在Clojure中正确构造字节数组的问题。

为了方便起见,在Tupelo库中提供了许多字符串和字符函数,这些函数适用于Clojure和ClojureScript,它们对“字符串”的概念有不同的理解。请参阅以下内容:

以下代码展示了一些操作java.lang.String、java.lang.Character、Byte、Long和Java字节数组类型值的方式:

(ns tst.demo.core
  (:use tupelo.test)
  (:require
    [cambium.core :as log]
    [clojure.string :as str]
    [tupelo.core :as t] ))

(dotest
  (let [chars-vec (vec "Hi") ; a vector of Character vals
        byte-vec  (mapv byte chars-vec) ; a vector of Byte vals
        long-vec  (mapv long chars-vec) ; a vector of Long vals

        ; Any sequence of numeric values is acceptable to the `byte-array` function. 
        ; The function `tupelo.core/char->codepoint` works in both CLJ and CLJS
        ba-nums   (byte-array (mapv t/char->codepoint chars-vec))
        ba-longs  (byte-array long-vec)

        ; a sequence of Characters can be made into a String in 2 ways
        str-0     (apply str chars-vec)
        str-1     (str/join chars-vec)

        ; Whether we have a vector or a byte-array, the values must be converted into
        ; a sequence of Characters before using `(apply str ...)` of `(str/join ...)`
        ; to construct a String object.
        str-2     (str/join (mapv char byte-vec))
        str-3     (str/join (mapv t/codepoint->char long-vec))
        str-4     (str/join (mapv char ba-nums))
        str-5     (str/join (mapv t/codepoint->char ba-longs))]

打印结果:
    (disp-types chars-vec)
    (disp-types byte-vec)
    (disp-types long-vec)
    (disp-types ba-nums)
    (disp-types ba-longs)

    (println "result type: " (type str-0))

以上所有的内容都会产生相同的结果:“Hi”
    (is= "Hi"
      str-0
      str-1
      str-2
      str-3
      str-4
      str-5)))

带有结果的


-------------------------------
   Clojure 1.10.1    Java 13
-------------------------------

Testing tst.demo.core
chars-vec   type:   clojure.lang.PersistentVector   value:   [H i]      content types:  [java.lang.Character java.lang.Character]
byte-vec    type:   clojure.lang.PersistentVector   value:   [72 105]   content types:  [java.lang.Byte java.lang.Byte]
long-vec    type:   clojure.lang.PersistentVector   value:   [72 105]   content types:  [java.lang.Long java.lang.Long]
ba-nums     type:   [B   value:   #object[[B 0x24a2bb25 [B@24a2bb25]    content types:  [java.lang.Byte java.lang.Byte]
ba-longs    type:   [B   value:   #object[[B 0x2434f548 [B@2434f548]    content types:  [java.lang.Byte java.lang.Byte]

result type:  java.lang.String


Ran 2 tests containing 1 assertions.
0 failures, 0 errors.

所有结果的类型都是java.lang.String


为了完整起见,这是显示代码:
(defn disp-types-impl
  [item]
  `(do
    (println '~item "  type:  " (type ~item) "  value:  " ~item
      "  content types: " (mapv type ~item))))

(defmacro disp-types
  [item]
  (disp-types-impl item))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接