为什么 Clojure 将字符串强制转换为具有缺点的字符

Why Clojure coerces string to character with cons

我在 REPL 中尝试序列并遇到以下行为,至少对我来说,这是非常不直观的。所以我评估了表达式 (cons '("1" "2") "3"),期望它产生 (("1" "2") "3"),但它却产生了 (("1" "2") )

有人可以解释为什么在这种情况下 Clojure 会自动将 string 强制转换为 character 吗?我假设这与字符串作为字符序列的内部表示有关。

它不是将字符串强制转换为字符,而是将字符串强制转换为字符序列,因为第二个参数必须是一个集合。

cons 将项目作为第一个参数,将集合作为第二个参数。通过 seq 函数将集合强制为列表。

user=> (seq "3")
()

如果您想使用 cons 将列表 ("1" "2") 添加到列表 ("3") 之前,您可以执行以下操作:

user=> (cons '("1" "2") '("3"))
(("1" "2") "3")

也许你想要 (("1" "2") . "3"),那种你可以在其他 lisp 中做的非列表 cons,但 Clojure 根本没有这种类型的 cons 对。

cons 的第二个参数是一个序列:

(cons x seq)

Returns a new seq where x is the first element and seq is the rest.

现在你应该知道,如果你不给它一个序列,clojure 会自动为你创建一个序列。例如,调用 seqcons 为您做的)会告诉您字符串已转换为字符序列:

(seq "32")
=> ( )

这是由 clojure 的 runtime in RT.java:

else if(coll instanceof CharSequence)
    return StringSeq.create((CharSequence) coll);

相反,如果您希望将角色视为单个项目,则可以将其包裹起来:

(cons '("1" "2") '("3"))
=> (("1" "2") "3")