Преобразование байтов в строку в ближайшем будущем - PullRequest
1 голос
/ 08 февраля 2020

Я преобразую байтовый массив в clojure в строку, и я столкнулся со странной проблемой, и я не знаю причину.

Массив байтов определяется как

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

когда я конвертирую его в вектор, он показывает

(vec a)

вывод: (105, 105, 105, ...... 68 раз ...., 105)

Вывод представляет собой массив из 105 с 72 элементами. Почему это так? Я пытаюсь преобразовать массив байтов в строку и с помощью

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

получается 72 я. С другой стороны, когда я делаю

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

, я получаю выходные данные H и I. Вот почему я пытаюсь преобразовать массив байтов в вектор. Если есть альтернативный способ сделать это, пожалуйста, дайте мне знать.

Ответы [ 2 ]

5 голосов
/ 08 февраля 2020

Вы вызываете двухартериальную версию, и поэтому ваш первый аргумент устанавливает size создаваемого массива, а ваш второй аргумент не является последовательностью, поэтому он считается 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"
0 голосов
/ 09 февраля 2020

@ cfrick уже ответил, как правильно построить байтовый массив в Clojure.

Для удобства, в библиотеке Tupelo есть много строковых и символьных функций, которые могут быть полезны , Они работают как в Clojure, так и в ClojureScript, которые имеют разные понятия о том, что такое «String». См. Следующее:

В следующем коде показаны некоторые способы управления значениями типа 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...