Clojure deftype中的可变字段?

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=&

我正在试用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=> (.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。除非您已经知道此警告不适用于您,并且理解我再次声明此警告的原因;-)