问题描述
现在我使用这个:
(instance?clojure.lang.IDeref x)
...但我怀疑可能有更好/更习惯的方式来做到这一点。
这是不正确的,你检查对象x是否实现了IDeref接口,这意味着你可以使用@符号解除引用对象。你想要的是这样:
(实例?clojure.lang.Ref x)
编辑:
(调整注释)。
你可以做你建议的,但是这有缺点,对其他用户做的扩展IDeref作为参考类型的对象分类。还要考虑vars也作为引用类型,但不使用IDeref接口。
这里有两个很好的选择。你可以写一个使用或语句的函数:
(def ref?[x]
实例?clojure.lang.Ref x)
(实例?clojure.lang.Agent x)
...))
或者你可以使用协议来定义一个新的谓词。这具有可扩展性的优点。
(defprotocol Ireference?(reference?[this]))
(extends-type java.lang.Object Ireference?(reference?[this] false))
(extend-type nil Ireference(reference?[this] false))
.lang.Ref Ireference?(reference?[this] true))
(extend-type clojure.lang.Agent Ireference?(reference?[this] true))
=> (reference?nil)
;; false
;; user => (reference?(ref 0))
;; true
href =http://dosync.posterous.com/51626638 =nofollow> http://dosync.posterous.com/51626638
For now I'm using this:
(instance? clojure.lang.IDeref x)
...but I suspect there might be a better/more idiomatic way to do this.
解决方案This is incorrect, you are checking if the object x implements the IDeref interface, which simply means you can dereference the object with the @ symbol. What you want is this:
(instance? clojure.lang.Ref x)
EDIT:
(Adjusting for comments).
You can do what you suggested but this has the disadvantage of classifying objects made by other users that extend IDeref to be considered a reference type. Also consider that vars also behave as reference types but do not use the IDeref interface.
There are two good options here. You can either write a function that uses an or statement:
(def ref? [x] (or (instance? clojure.lang.Ref x) (instance? clojure.lang.Agent x) ...))
Or you can use protocols to define a new predicate. This has the advantage of being extensible.
(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
For another example see http://dosync.posterous.com/51626638
这篇关于我们如何测试某事是否是参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!