设置在Racket中定义的同一类的另一个对象实例的私有字段

时间:2016-12-19 16:55:01

标签: class object field racket

我想说我在Racket中有一个名为five%的课程:

(define five%
  (class object%
    (super-new)
    (define internal 5)
    (define/public (get-number)
      internal)))

让我们说我已经定义了两个五个:

(define f (new five%))
(define g (new five%))

现在,fg都可以访问自己的internal字段。但是我可以说我想向five%添加一个函数,称为change-other,它接收另一个five%对象,并修改它的internal字段。说这样的话:

(define/public (change-other other)
  (set-field! internal other 4))

现在,显然我不能这样做,因为internal是私有字段,因此five%的任何其他实例都无法访问它。

那么,在Racket中是否可以创建一个具有私有字段的类,只能由该类的其他实例访问?

1 个答案:

答案 0 :(得分:2)

诀窍是公开该字段,然后使用define-local-member-name将其设为私有。

代码如下:

$ python -O -m timeit "from testscript3 import doit" "doit()"
100 loops, best of 3: 3.41 msec per loop

(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])将其转换为类范围之外的私有字段。

现在,我们可以创建两个(define-local-member-name internal)个对象:

five%

在repl中,我们看到(define f (new five%)) (define g (new five%)) 可以改变g的字段:

f

但我们不能直接改变它:

> (send g change-other f)
> (send f get-number)
4

感谢Asumu帮助解决这个问题。