Clojure 我们如何测试某个东西是否是引用?

Clojure 我们如何测试某个东西是否是引用?,clojure,Clojure,现在我用的是: (实例?clojure.lang.IDeref x) …但我怀疑可能有更好/更惯用的方法来实现这一点。这是错误的,您正在检查对象x是否实现了IDeref接口,这意味着您可以使用@符号取消对对象的引用。你想要的是: (instance? clojure.lang.Ref x) 编辑: (根据评论进行调整) 您可以按照您的建议进行操作,但这样做的缺点是对其他用户创建的对象进行分类,这些用户将IDeref扩展为引用类型。还考虑VARS也作为引用类型,但不使用IDREF接口。 这里有

现在我用的是:

(实例?clojure.lang.IDeref x)


…但我怀疑可能有更好/更惯用的方法来实现这一点。

这是错误的,您正在检查对象x是否实现了IDeref接口,这意味着您可以使用@符号取消对对象的引用。你想要的是:

 (instance? clojure.lang.Ref x)
编辑:

(根据评论进行调整)

您可以按照您的建议进行操作,但这样做的缺点是对其他用户创建的对象进行分类,这些用户将IDeref扩展为引用类型。还考虑VARS也作为引用类型,但不使用IDREF接口。

这里有两个很好的选择。您可以编写使用or语句的函数:

 (def ref? [x] 
    (or (instance? clojure.lang.Ref x)
        (instance? clojure.lang.Agent x)
        ...))
也可以使用协议定义新的谓词。这具有可扩展的优点

 (defprotocol Ireference? (reference? [this]))

 (extend-type java.lang.Object Ireference? (reference? [this] false))
 (extend-type nil Ireference (reference? [this] false))
 (extend-type clojure.lang.Ref Ireference? (reference? [this] true))
 (extend-type clojure.lang.Agent Ireference? (reference? [this] true))

 ;;user=> (reference? nil)
 ;;false
 ;;user=> (reference? (ref 0))
 ;;true

再举一个例子,请看

我还将更进一步,使其成为一个新的谓词,如
(defn ref?[x](instance?clojure.lang.ref x))
bmillare:我实际上询问的是所有的“references”,而不仅仅是“ref”,而且afaik,术语“references”包括refs,原子和代理。还要注意,不能将case与类文本一起使用:
(case(class“hi”)String true false)->false
修复了类文本问题(extend type nil irereference?(reference?[this]false])缺少第一个问号。顺便说一句,谢谢。知道为什么没有参考资料吗?clojure.core中的函数?有一个JIRA open可以为该类型和其他内置类型添加谓词: