我们如何测试某事是否是参考? [英] How do we test whether something is a reference?

查看:127
本文介绍了我们如何测试某事是否是参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我使用这个:



(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

这篇关于我们如何测试某事是否是参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆