【问题标题】:In clojure, why the type of an empty list is different from that of non-empty lists?在clojure中,为什么空列表的类型与非空列表的类型不同?
【发布时间】:2013-02-01 06:58:19
【问题描述】:

我想判断两个值是否属于同一类型,但是发现空列表的类型是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=> 

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

【问题讨论】:

  • EmptyList 只是 IPersistentList 的实现,我想它是由性能原因创建的。而且似乎没有任何其他方法可以比较两个元素的类型。但可能功能 list? 会对您的情况有所帮助。

标签: clojure


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-26
    • 2014-02-07
    • 2017-12-29
    • 2016-01-19
    • 2020-09-11
    • 2010-12-02
    • 2017-03-21
    相关资源
    最近更新 更多