在clojure中,为什么空列表的类型与非空列表的类型不同?

Jav*_*ran 4 clojure

我想判断两个值是否属于同一类型,但我发现空列表的类型clojure.lang.PersistentList$EmptyList不是clojure.lang.PersistentList.

user=> (def la '())
#'user/la
user=> (def lb '(1 2))
#'user/lb
user=> (def t (map type [la lb]))
#'user/t
user=> t
(clojure.lang.PersistentList$EmptyList clojure.lang.PersistentList)
user=> (apply = t)
false
user=> 
Run Code Online (Sandbox Code Playgroud)

所以,我想知道为什么空列表的类型与非空列表的类型不同,以及判断两个事物是否属于同一类型的正确方法是什么?

mik*_*era 10

不要依赖于具体类型的Clojure数据结构.它们是未记录的实现细节,您无法保证它们在将来的Clojure版本中不会更改.

它是更安全依赖于抽象(例如,通过定义IPersistentListISeq接口).这些不太可能以可能破坏你的代码的方式改变(我的理解是Rich Hickey在抽象方面对后向兼容性非常大.如果你依赖于具体的实现,我相信他会说这是你自己的错如果事情破裂)

更好的是,您应该使用clojure.core诸如seq?或之类的函数list?,具体取决于您想要检测的内容.这些不仅可能长时间保持向后兼容性,而且还有机会在非JVM版本的Clojure上正常工作(例如ClojureScript).