64

假设我有一个类似java.lang.CharacterLazySeq

(\b \ \! \/ \b \ \% \1 \9 \/ \. \i \% \$ \i \space \^@)

如何将其转换为字符串?我已经尝试了明显的

(String. my-char-seq)

但它抛出

java.lang.IllegalArgumentException: No matching ctor found for class java.lang.String (NO_SOURCE_FILE:0)
[Thrown class clojure.lang.Compiler$CompilerException]

我认为是因为 String 构造函数需要一个原始的char[]而不是LazySeq。所以然后我尝试了类似的东西

(String. (into-array my-char-seq))

但它抛出了同样的异常。现在的问题是into-array正在返回java.lang.Character[]而不是原始的char[]。这令人沮丧,因为我实际上像这样生成我的字符序列

(map #(char (Integer. %)) seq-of-ascii-ints)

基本上我有一个表示 ASCII 字符的整数序列;65 = A 等。你可以看到我明确地使用了原始类型强制函数(char x)

这意味着我的map函数正在返回一个原始字符,但 Clojure 的map函数总体上正在返回java.lang.Character对象。

4

3 回答 3

128

这有效:

(apply str my-char-seq)

基本上,str在其每个 args 上调用 toString() ,然后将它们连接起来。这里我们使用apply将序列中的字符作为 args 传递给str

于 2009-11-06T14:30:41.290 回答
14

另一种方法是使用clojure.string/join,如下:

(require '[clojure.string :as str] )
(assert (= (vec "abcd")                [\a \b \c \d] ))
(assert (= (str/join  (vec "abcd"))    "abcd" ))
(assert (= (apply str (vec "abcd"))    "abcd" ))

还有一种clojure.string/join接受分隔符的替代形式。看:

http://clojuredocs.org/clojure_core/clojure.string/join

对于更复杂的问题,您可能还希望strcat 从 Tupelo 库中查看:

(require '[tupelo.core :as t] )
(prn (t/strcat "I " [ \h \a nil \v [\e \space (byte-array [97])
                  [ nil 32 "complicated" (Math/pow 2 5) '( "str" nil "ing") ]]] ))
;=> "I have a complicated string"
于 2014-02-01T21:21:08.130 回答
9

作为一种特殊情况,如果相关序列的基础类型是,clojure.lang.StringSeq您还可以执行以下操作:

(.s (my-seq))

这是非常高效的,因为它只是从 clojure StringSeq 类中提取公共最终 CharSequence 字段。

例子:

(type (seq "foo"))
=> clojure.lang.StringSeq

(.s (seq "foo"))
=> "foo"

(type (.s (seq "foo")))
=> java.lang.String

时间含义的示例(并注意使用类型提示时的区别):

(time 
  (let [q (seq "xxxxxxxxxxxxxxxxxxxx")]
    (dotimes [_ 1000000]
      (apply str q))))
"Elapsed time: 620.943971 msecs"
=> nil

(time 
  (let [q (seq "xxxxxxxxxxxxxxxxxxxx")]
    (dotimes [_ 1000000]
      (.s q))))
"Elapsed time: 1232.119319 msecs"
=> nil

(time 
  (let [^StringSeq q (seq "xxxxxxxxxxxxxxxxxxxx")]
    (dotimes [_ 1000000]
      (.s q))))
"Elapsed time: 3.339613 msecs"
=> nil
于 2017-04-26T08:09:22.357 回答