我在Clojure 1.2.1中看到了这种行为:
user=> (type '(1 2))
clojure.lang.PersistentList
user=> (type `(1 2)) ;; notice syntax-quote
clojure.lang.Cons
user=> (type '(1))
clojure.lang.PersistentList
user=> (type `(1))
clojure.lang.PersistentList
Run Code Online (Sandbox Code Playgroud)
我希望`(1)成为一个缺点,就像`(1 2)那样.
我也尝试过:
user=> (type (cons 1 nil))
clojure.lang.PersistentList
user=> (type (cons 1 `()))
clojure.lang.Cons
user=> (type (cons 1 '()))
clojure.lang.Cons
user=> (type (cons 1 []))
clojure.lang.Cons
Run Code Online (Sandbox Code Playgroud)
那么`(1)和(cons 1 nil)成为PersistentLists的原因是什么?
就像 amalloy 所说,您不应该针对这些确切类型进行编程,而应该针对seq抽象进行编程。
不过,我想我可以猜测一下原因。Clojure 表单生成PersistentList最终调用RT.java,特别是cons(Object x, Object coll)方法。它以一个非常奇怪的检查开始:如果该检查没有通过,if(coll == null) return new PersistentList(x)那么它会创建一个对象。Cons如果您查看早期版本的代码,您可以发现:
static public IPersistentCollection cons(Object x, IPersistentCollection y) {
if(y == null)
return new PersistentList(x);
return y.cons(x);
}
Run Code Online (Sandbox Code Playgroud)
因此,在该函数的早期版本中,调用被分派到第二个参数的方法,因此第二个参数(即在 Clojure 中)cons的情况需要特殊处理。更高版本不执行该调度(或者实际上以不同的方式执行此操作,大概是为了支持更多种类的集合类型),但该检查已保留,因为它不会破坏任何正确编写的代码。nullnil
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |