这是不正确的,您正在检查对象 x 是否实现了 IDeref 接口,这仅意味着您可以使用 @ 符号取消引用该对象。你想要的是这个:
(instance? clojure.lang.Ref x)
Run Code Online (Sandbox Code Playgroud)
编辑:
(调整评论)。
您可以按照您的建议进行操作,但这有一个缺点,即对扩展 IDeref 的其他用户创建的对象进行分类以被视为引用类型。还要考虑 vars 也作为引用类型,但不使用 IDeref 接口。
这里有两个不错的选择。您可以编写一个使用 or 语句的函数:
(def ref? [x]
(or (instance? clojure.lang.Ref x)
(instance? clojure.lang.Agent x)
...))
Run Code Online (Sandbox Code Playgroud)
或者您可以使用协议来定义新的谓词。这具有可扩展的优点。
(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
Run Code Online (Sandbox Code Playgroud)
另一个例子见http://dosync.posterous.com/51626638
| 归档时间: |
|
| 查看次数: |
1262 次 |
| 最近记录: |