我怎样才能将字符LazySeq转换为Clojure中的string?

比方说,我有一个 java.lang.Character一样的LazySeq

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

我怎样才能将其转换为string? 我已经尝试了明显的

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

但它会抛出同样的exception。 现在的问题是, 数组是返回一个java.lang.Character []而不是一个原始的字符[] 。 这是令人沮丧的,因为我实际上是这样产生我的字符序列

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

基本上我有一个代表ASCII字符的整数, 65 = A等你可以看到我明确地使用了原始types强制函数(char x)

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

这工作:

 (apply str my-char-seq) 

基本上, str在每个参数上调用toString(),然后连接它们。 这里我们使用apply将序列中的字符作为parameter passing给str

另一种方法是使用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有一个替代forms,它接受一个分隔符。 看到:

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

对于更复杂的问题,你也可以从图珀洛图书馆看看strcat

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

作为一个特例,如果序列的基础types是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 

时间影响的一个例子(并注意使用types提示时的差异):

 (time (let [q (seq "xxxxxxxxxxxxxxxxxxxx")] (dotimes [_ 1000000] (apply str q)))) "Elapsed time: 620.943971 msecs" => nil (time (let [q (seq "xxxxxxxxxxxxxxxxxxxx")] (dotimes [_ 1000000] (.sq)))) "Elapsed time: 1232.119319 msecs" => nil (time (let [^StringSeq q (seq "xxxxxxxxxxxxxxxxxxxx")] (dotimes [_ 1000000] (.sq)))) "Elapsed time: 3.339613 msecs" => nil