设置在 Racket 中定义的相同 class 的另一个对象实例的私有字段
Setting private fields of another object instance of the same class being defined in Racket
假设我在 Racket 中有一些 class 叫做 five%
:
(define five%
(class object%
(super-new)
(define internal 5)
(define/public (get-number)
internal)))
假设我定义了两个五:
(define f (new five%))
(define g (new five%))
现在,f
和 g
都可以访问他们自己的 internal
字段。但是假设我想向 five%
添加一个函数,称为 change-other
,它接受另一个 five%
对象,并修改它的 internal
字段。像这样说:
(define/public (change-other other)
(set-field! internal other 4))
现在,显然我不能这样做,因为 internal
是一个私有字段,因此它不能被 five%
的任何其他实例访问。
那么,是否可以在 Racket 中创建一个带有私有字段的 class,它只能被该 class 的其他实例访问?
诀窍是将字段设置为 public,然后使用 define-local-member-name
将其设为私有。
代码如下所示:
(define five%
(let ()
(define-local-member-name internal)
(class object%
(super-new)
(field [internal 5])
(define/public (change-other other)
(set-field! internal other 4))
(define/public (get-number)
internal))))
第 (field [internal 5])
行替换了私有字段的定义,并创建了一个 public 变体。
然后,在class相同的范围内,我们使用(define-local-member-name internal)
,将其转为class范围之外的私有字段。
现在,我们可以创建两个 five%
对象:
(define f (new five%))
(define g (new five%))
并且在 repl 中,我们看到 g
可以改变 f
的字段:
> (send g change-other f)
> (send f get-number)
4
但是我们不能直接改变它:
> (get-field internal f)
get-field: given object does not have the requested field
field name: internal
object: (object:five% ...)
感谢 Asumu 帮助回答这个问题。
假设我在 Racket 中有一些 class 叫做 five%
:
(define five%
(class object%
(super-new)
(define internal 5)
(define/public (get-number)
internal)))
假设我定义了两个五:
(define f (new five%))
(define g (new five%))
现在,f
和 g
都可以访问他们自己的 internal
字段。但是假设我想向 five%
添加一个函数,称为 change-other
,它接受另一个 five%
对象,并修改它的 internal
字段。像这样说:
(define/public (change-other other)
(set-field! internal other 4))
现在,显然我不能这样做,因为 internal
是一个私有字段,因此它不能被 five%
的任何其他实例访问。
那么,是否可以在 Racket 中创建一个带有私有字段的 class,它只能被该 class 的其他实例访问?
诀窍是将字段设置为 public,然后使用 define-local-member-name
将其设为私有。
代码如下所示:
(define five%
(let ()
(define-local-member-name internal)
(class object%
(super-new)
(field [internal 5])
(define/public (change-other other)
(set-field! internal other 4))
(define/public (get-number)
internal))))
第 (field [internal 5])
行替换了私有字段的定义,并创建了一个 public 变体。
然后,在class相同的范围内,我们使用(define-local-member-name internal)
,将其转为class范围之外的私有字段。
现在,我们可以创建两个 five%
对象:
(define f (new five%))
(define g (new five%))
并且在 repl 中,我们看到 g
可以改变 f
的字段:
> (send g change-other f)
> (send f get-number)
4
但是我们不能直接改变它:
> (get-field internal f)
get-field: given object does not have the requested field
field name: internal
object: (object:five% ...)
感谢 Asumu 帮助回答这个问题。