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

时间:2013-02-16 10:33:04

标签: 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=> 

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

1 个答案:

答案 0 :(得分:10)

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

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

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