我正在尝试 Clojure 1.2,特别是受支持的可变字段deftype
根据clojure.org 文档 http://clojure.org/datatypes.
但我无法让装置工作。更新字段的语法是什么?或者可变性还没有实现吗?
(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)))
还有:unsynchronized-mutable
。区别正如经验丰富的 Java 开发人员从名称中所暗示的那样。 ;-) 请注意,提供任一注释都会产生使字段私有的额外效果,因此不再可能直接访问字段:
(.getX (Point. 10)) ; still works
(.x (Point. 10)) ; with annotations -- IllegalArgumentException, works without
另外,1.2 可能会支持语法^:volatile-mutable x
作为简写^{:volatile-mutable true} x
(这已经在一些新的数字分支上可用)。
这两个选项都在(doc deftype)
;相关部分如下——请注意警告!
字段可以被限定
与元数据 :volatile-mutable true 或 :unsynchronized-mutable
true,此时方法将支持 (set!afield aval)
身体。请注意,可变字段极难使用
正确,并且存在只是为了促进更高的建设
Clojure 中的级别构造,例如 Clojure 的引用类型
本身。它们仅供专家使用 - 如果语义和
:volatile-mutable 或 :unsynchronized-mutable 的含义不是
您立刻就会明白,您不应该使用它们。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)