我来Clojure语言时间不长,正试图通过deftype定义一个包含可变字段的类,以下是定义。
我的程序是单线程的,没有人会使用我的代码,我已经承诺了。我知道不可变性的优点,但这个程序有超过5亿次更新,所以垃圾收集器将是主要的行为者,而不是我的代码。我已经试过了。
我在运行时遇到了两个问题。
*1. ; Execution error (IllegalArgumentException) at layout.core.Individual/idivlCopy (core.clj:161).
; No matching field found: fitness for class layout.core.Individual
我明白deftype的字段不是公共的,但idivlCopy的代码在deftype内部。在我看来,运行时似乎知道(.fitness this),但不熟悉(.fitness that)。
- 这种行为的理由是什么?我如何解决这个问题呢?
- 我怎么从私有(即deftype)代码区域访问私有的受保护的字段(that)?!
`
*2. ; Execution error (ClassCastException) at layout.core.Individual/idivlSwap (core.clj:173).
; class clojure.core.Vec cannot be cast to class clojure.lang.IEditableCollection
; (clojure.core.Vec and clojure.lang.IEditableCollection are in unnamed module of loader 'app')
`
- 注释说明这两个字段都是volatile-mutable的。为什么染色体向量在运行时不了解这一点?为什么我不能以volatile-mutable染色体向量-of :char-{ 的形式进行(assoc!)操作?
(definterface IIndividual
(idivlCopy [that]) ; Copies that Individual to this
(idivlSwap [^Integer xP, ^Integer xQ])) ; Swaps two genes in the chromosome
; and somme more.
)
(deftype Individual ; An individual has a fitness value and a chromosome
[^{:volatile-mutable true} ^Integer fitness, ; Integer
^{:volatile-mutable true} chromosome] ; vector-of :char
IIndividual
:
.
(idivlCopy ; Copies that Individual to this
[_, that]
*1 (set! fitness (.fitness that)) ; (set! fitness 999) worked!!
(set! chromosome (.chromosome that))
nil)
(idivlSwap ; Swaps the genes in the chromosome at alleles P and Q
[this,
^Integer iP, ; index of allele P
^Integer iQ] ; index of allele Q
(let [gP (chromosome iP), ; gene at allele P
gQ (chromosome iQ)] ; gene at allele Q
*2 (assoc! chromosome iP gQ)
(assoc! chromosome iQ gP)
nil))
; and some more
:
.
)