简体   繁体   English

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

[英]Converting bytes to string in clojure

I am converting a byte array in clojure into a string and I am facing a weird problem and I don't know the reason why.我正在将 clojure 中的字节数组转换为字符串,但我面临一个奇怪的问题,我不知道原因。

The byte array is defined as字节数组定义为

(def a (byte-array  (byte 72) (byte 105)))

when I convert it into a vector it shows当我将其转换为矢量时,它会显示

(vec a)

output: (105, 105, 105, ......68 times ...., 105)输出:(105、105、105、......68次......、105)

The output is an array of 105 with 72 elements.输出是一个包含 72 个元素的 105 个数组。 Why is it so?为什么会这样? I am trying to convert a byte array into a string and using我正在尝试将字节数组转换为字符串并使用

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

yields 72 i's.产生 72 个 i。 On the other hand when I do另一方面,当我做

(map char [(byte 72) (byte 105)])

I get the output H and I. That's why I am trying to convert the byte array into a vector.我得到输出 H 和 I。这就是我试图将字节数组转换为向量的原因。 If there is an alternate way of doing it please let me know.如果有替代方法,请告诉我。

You are calling the two-arity version and therefor your first argument sets the size of the array to be created and your second argument is no sequence so it is considered the init-val ;您正在调用双元版本,因此您的第一个参数设置要创建的数组的size ,而您的第二个参数没有序列,因此它被视为init-val see:看:

user=> (doc byte-array)
-------------------------
clojure.core/byte-array
([size-or-seq] [size init-val-or-seq])
  Creates an array of bytes

Also the initial values are taken from a sequence (as the argument name suggests).此外,初始值取自序列(如参数名称所示)。 So you can do:所以你可以这样做:

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

@cfrick has already answered how to properly construct a byte array in Clojure. @cfrick 已经回答了如何在 Clojure 中正确构造字节数组。

As a convenience, there are many string and character functions available in the Tupelo library that may be useful.为方便起见, Tupelo 库中提供了许多可能有用的字符串和字符函数。 These work in both Clojure and ClojureScript, which have different notions of what a "String" is.这些在 Clojure 和 ClojureScript 中都有效,它们对什么是“字符串”有不同的概念。 See the following:请参阅以下内容:

The following code shows some of the ways you can manipulate values of type java.lang.String, java.lang.Character, Byte, Long, and Java byte array:以下代码显示了可以操作 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))]

print the results:打印结果:

    (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))

All of the above produce the same result "Hi"以上所有产生相同的结果“嗨”

    (is= "Hi"
      str-0
      str-1
      str-2
      str-3
      str-4
      str-5)))

with result结果

-------------------------------
   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.

And all of the results are of type java.lang.String .所有结果都是java.lang.String类型。


For completeness, here is the display code:为了完整起见,这里是显示代码:

(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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM