Rob*_*ell 54 types clojure map coercion primitive-types
比方说,我有一个LazySeq的java.lang.Character中的像
(\b \ \! \/ \b \ \% \1 \9 \/ \. \i \% \$ \i \space \^@)
Run Code Online (Sandbox Code Playgroud)
如何将其转换为String?我已经尝试过显而易见的事了
(String. my-char-seq)
Run Code Online (Sandbox Code Playgroud)
但它会抛出
java.lang.IllegalArgumentException: No matching ctor found for class java.lang.String (NO_SOURCE_FILE:0)
[Thrown class clojure.lang.Compiler$CompilerException]
Run Code Online (Sandbox Code Playgroud)
我认为因为String构造函数需要原始char []而不是LazySeq.那么我尝试了类似的东西
(String. (into-array my-char-seq))
Run Code Online (Sandbox Code Playgroud)
但它抛出同样的异常.现在的问题是into-array返回java.lang.Character []而不是原始char [].这很令人沮丧,因为我实际上是这样生成我的角色序列
(map #(char (Integer. %)) seq-of-ascii-ints)
Run Code Online (Sandbox Code Playgroud)
基本上我有一个表示ASCII字符的seq的整数; 65 = A等.您可以看到我明确使用原始类型强制函数(char x).
这意味着我的map函数返回一个原始char,但Clojure map函数整体返回java.lang.Character对象.
Sid*_*ddy 107
这有效:
(apply str my-char-seq)
Run Code Online (Sandbox Code Playgroud)
基本上,str在每个args上调用toString()然后连接它们.这里我们使用apply将序列中的字符作为args传递给str.
Ala*_*son 11
另一种方法是使用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" ))
Run Code Online (Sandbox Code Playgroud)
有一种替代形式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"
Run Code Online (Sandbox Code Playgroud)
作为一种特殊情况,如果相关序列的基础类型是clojure.lang.StringSeq您也可以:
(.s (my-seq))
Run Code Online (Sandbox Code Playgroud)
这是非常高效的,因为它只是从clojure StringSeq类中拉出公共最终的CharSequence字段.
例:
(type (seq "foo"))
=> clojure.lang.StringSeq
(.s (seq "foo"))
=> "foo"
(type (.s (seq "foo")))
=> java.lang.String
Run Code Online (Sandbox Code Playgroud)
时间影响的一个例子(并注意使用类型提示时的差异):
(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
Run Code Online (Sandbox Code Playgroud)