我们如何测试某些东西是否为参考?

时间:2011-09-03 13:09:25

标签: clojure

现在我正在使用它:

(instance? clojure.lang.IDeref x)

...但我怀疑可能有更好/更惯用的方法来做到这一点。

1 个答案:

答案 0 :(得分:4)

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

 (instance? clojure.lang.Ref x)

编辑:

(调整评论)。

您可以执行您的建议,但这样做的缺点是将其他用户将扩展IDeref的对象分类为引用类型。还要考虑vars也表现为引用类型,但不使用IDeref接口。

这里有两个不错的选择。您可以编写使用或声明的函数:

 (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

有关其他示例,请参阅http://dosync.posterous.com/51626638