【问题标题】:Why Clojure coerces string to character with cons为什么 Clojure 使用 cons 将字符串强制转换为字符
【发布时间】:2015-08-30 14:53:05
【问题描述】:

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

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

【问题讨论】:

  • cons 强制字符串,不是字符,而是字符sequence

标签: clojure sequence cons


【解决方案1】:

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

(cons x seq)

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

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

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

这是由 clojure 的 runtime in RT.java 完成的:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      相关资源
      最近更新 更多