球拍的class
有一个private
表单,可用于隐藏方法。这似乎模仿了Java或C#等其他语言中私有的使用。 The docs显示了使用私有隐藏方法的示例:
(define light%
(class object%
(super-new)
(define on? #t)
(define (toggle) (set! on? (not on?)))
(private toggle)
(define (flick) (toggle))
(public flick)))
> (send (new light%) toggle)
send: no such method
method name: toggle
class name: light%
> (send (new light%) flick)
但是,默认情况下,方法似乎是私有的,无论是否实际使用private
关键字。例如,从文档修改示例会产生相同的结果:
(define light%
(class object%
(super-new)
(define on? #t)
(define (toggle) (set! on? (not on?)))
(define (flick) (toggle))
(public flick)))
> (send (new light%) toggle)
send: no such method
method name: toggle
class name: light%
> (send (new light%) flick)
在这两种情况下,课程范围之外的范围都无法访问toggle
,但是flick
可以访问,因为它标记为public
。
那么,private
用于什么,为什么它仍然在语言中?
答案 0 :(得分:1)
在第二种情况下,toggle
不是一种方法;它是一个私有字段,其值是一个闭包。特别是,为每个toggle
对象分配了一个新的light%
闭包。
使用(private toggle)
,toggle
方法定义被转换为为this
获取额外的参数,并且通过该参数解析字段引用。像这样:
(define (toggle-impl this-obj)
(set-light%-on?! this-obj (not (light%-on? this-obj))))
由于它不再关闭this
,因此该过程可以与该类同时分配一次。 class
宏将toggle
绑定到宏,该宏重写对toggle
的所有调用以传递隐式this
参数。 (这就是为什么方法名称不是值;如果你想在列表上map
方法,你必须进行eta扩展,以便方法名称在操作员位置。)