2

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

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

4

2 回答 2

4

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

(缺点 x seq)

返回一个新的 seq,其中 x 是第一个元素,seq 是其余的。

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

(seq "32")
=> (\3 \2)

这是由 clojure在 RT.java 中的运行时完成的:

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

相反,如果您希望将字符视为单个项目,则可以将其包装:

(cons '("1" "2") '("3"))
=> (("1" "2") "3")
于 2015-08-30T15:33:20.360 回答
0

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

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

user=> (seq "3")
(\3)

如果要使用cons将列表添加("1" "2")到列表中,("3")则可以执行以下操作:

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

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

于 2015-08-30T15:33:06.657 回答