现在我正在使用这个:
(instance? clojure.lang.IDeref x)
...但我怀疑可能有更好/更惯用的方法来做到这一点。
这是不正确的,您正在检查对象 x 是否实现了 IDeref 接口,这仅仅意味着您可以使用 @ 符号取消引用该对象。你想要的是这样的:
(instance? clojure.lang.Ref x)
EDIT:
(根据评论进行调整)。
您可以按照您的建议进行操作,但这有一个缺点,即对其他用户创建的扩展 IDeref 的对象进行分类以将其视为引用类型。另请考虑,变量也充当引用类型,但不使用 IDeref 接口。
这里有两个不错的选择。您可以编写一个使用 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
另一个例子参见http://dosync.posterous.com/51626638 http://dosync.posterous.com/51626638
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)