Mutable字段在Clojure deftype? [英] Mutable fields in Clojure deftype?

查看:183
本文介绍了Mutable字段在Clojure deftype?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着Clojure 1.2,特别是在 deftype 中支持的可变字段,根据 clojure.org文档

I'm trying out Clojure 1.2, specifically mutable fields which are supported in deftype according to the clojure.org documentation.

但我无法使设置工作。更新字段的语法是什么?

But I can't get the set to work. What is the syntax for updating a field? Or isn't mutability implemented yet?

(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快照。

Using a 1.2 snapshot from a few days ago.

推荐答案

deftype 的默认值仍然是字段是不可变的;要覆盖此,您需要注释要用适当的元数据可变的字段的名称。此外,实例字段的 set!的语法也不同。使上述工作成功的示例实现:

deftype's default is still to have the fields be immutable; to override this, you need to annotate the names of the fields which are to be mutable with appropriate metadata. Also, the syntax for set! of instance fields is different. An example implementation to make the above work:

(deftype Point [^{:volatile-mutable true} x]
  IPoint
  (getX [_] x)
  (setX [this v] (set! x v)))

还有:unsynchronized-mutable 。区别是名字向有经验的Java开发人员建议。 ;-)请注意,提供注释还具有将字段设为私有的额外效果,因此无法再进行直接字段访问:

There's also :unsynchronized-mutable. The difference is as the names would suggest to an experienced Java developer. ;-) Note that providing either annotation has the additional effect of making the field private, so that direct field access is no longer possible:

(.getX (Point. 10)) ; still works
(.x (Point. 10))    ; with annotations -- IllegalArgumentException, works without

此外,1.2可能支持语法 ^:volatile-mutable x 作为 ^ {:volatile-mutable true} x 的简写(这已经在一些新的数字分支)。

Also, 1.2 will likely support the syntax ^:volatile-mutable x as shorthand for ^{:volatile-mutable true} x (this is already available on some of the new numerics branches).

(doc deftype)


字段可以通过元数据限定
:volatile-mutable true或: unsynchronized-mutable
true,此时(set!afield aval)将在方法
中支持。请注意,可变字段非常难以正确使用
,并且只是为了便于在Clojure
本身中构建更高的
级别构造,例如Clojure的引用类型。它们仅供专家使用 - 如果语法和
的影响:volatile-mutable或:unsynchronized-mutable不是
立即显现给你,你不应该使用它们。

Fields can be qualified with the metadata :volatile-mutable true or :unsynchronized-mutable true, at which point (set! afield aval) will be supported in method bodies. Note well that mutable fields are extremely difficult to use correctly, and are present only to facilitate the building of higher level constructs, such as Clojure's reference types, in Clojure itself. They are for experts only - if the semantics and implications of :volatile-mutable or :unsynchronized-mutable are not immediately apparent to you, you should not be using them.

这篇关于Mutable字段在Clojure deftype?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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