Clojure deftype中的可变字段?
我正在试用Clojure 1.2,特别是根据 但是我不能让电视机工作。更新字段的语法是什么?或者说可变性还没有实现Clojure deftype中的可变字段?,clojure,deftype,Clojure,Deftype,我正在试用Clojure 1.2,特别是根据 但是我不能让电视机工作。更新字段的语法是什么?或者说可变性还没有实现 (definterface IPoint (getX []) (setX [v])) (deftype Point [x] IPoint (getX [this] x) (setX [this v] (set! (.x this) v))) user=> (def p (Point. 10)) user=> (.getX p) 10 user=&
(definterface IPoint
(getX [])
(setX [v]))
(deftype Point [x]
IPoint
(getX [this] x)
(setX [this v] (set! (.x this) v)))
user=> (def p (Point. 10))
user=> (.getX p)
10
user=> (.setX p 20)
ClassCastException: user.Point cannot be cast to compile__stub.user.Point
使用几天前的1.2快照。
deftype
的默认设置仍然是字段不可变;若要覆盖此项,您需要对字段的名称进行注释,这些字段可以使用适当的元数据进行修改。还有,set实例字段的代码>不同。实现上述功能的示例:
(deftype Point [^{:volatile-mutable true} x]
IPoint
(getX [_] x)
(setX [this v] (set! x v)))
还有:未同步的可变。不同之处在于,这些名字对一位经验丰富的Java开发人员来说意味着什么请注意,提供任一注释都会使字段变为私有,从而使直接字段访问不再可能:
(.getX (Point. 10)) ; still works
(.x (Point. 10)) ; with annotations -- IllegalArgumentException, works without
此外,1.2可能会支持语法^:volatile mutable x
作为^{:volatile mutable true}x
的缩写(这在一些新的numerics分支上已经可用)
这两个选项都在(doc deftype)
中提到;相关部分如下——注意警告
字段可以被限定
使用元数据:volatile mutable true或:unsynchronized mutable
true,在该点(set!afield aval)将在方法中受支持
身体。请注意,可变字段非常难以使用
正确,且仅用于促进更高层次的建筑
Clojure中的级别构造,如Clojure的引用类型
它本身它们仅供专家使用-如果语义和
:volatile mutable或:unsynchronized mutable的含义不是
很明显,你不应该使用它们
与Clojure中的大多数内容一样,通过deftype
定义的类型中的字段是不可变的。虽然您可以使用:volatile mutable
/:unsynchronized mutable
注释来避免这种情况,但这样做并不常见。首先,这样的注释将使字段私有,因此只有在类型上定义的方法才能访问(并设置)它。但更重要的是,这种结构容易受到数据竞争的影响
当需要可变性时,idomatic Clojure将使用Clojure的一种引用类型,如or。谢谢。你是信息的金矿,很高兴你在这里:)我想强调。。。再一次。。。“你不应该使用它们”。不要使用:volatile mutable和:unsynchronized mutable。除非您已经知道此警告不适用于您,并且理解我再次声明此警告的原因;-)