Class 如何重写类中字段的默认值?
这是迄今为止我发现的覆盖类中默认字段值的最佳方法:Class 如何重写类中字段的默认值?,class,inheritance,field,racket,default-value,Class,Inheritance,Field,Racket,Default Value,这是迄今为止我发现的覆盖类中默认字段值的最佳方法: (define sa-canvas% (class canvas% . . . (init-field [min-width 600] [min-height 300] [stretchable-width #f] [stretchable-height #f]) (super-new [min-width min-wid
(define sa-canvas%
(class canvas%
. . .
(init-field [min-width 600]
[min-height 300]
[stretchable-width #f]
[stretchable-height #f])
(super-new [min-width min-width]
[min-height min-height]
[stretchable-width stretchable-width]
[stretchable-height stretchable-height])
. . .))
这似乎太冗长了。Racket的类系统设计支持的预期方式是什么?首先,您的示例做了一些您可能不想要的事情。使用
init field
在初始化为相应初始化参数的类实例上创建一个可变的公共字段。这些并不经常使用:更常见的是使用私有字段(即define
)和getter方法,如果您想支持变异,可以使用setter。事实上,我们可以看出,尽管canvas%
使用了这些初始化参数,但它并没有将它们存储为公共字段,因为(与方法一样)类不能创建与其超类字段具有相同外部名称的新字段。(字段可以通过继承字段
继承)例如,计算此表达式会引发异常:
(class (class object%
(init-field [x 1])
(super-new))
(init-field [x 2])
(super-new [x x]))
对于不希望保留为字段的初始化参数,请使用init
而不是init field
。此表达式与示例相同,但不创建字段:
(class canvas%
(init [min-width 600]
[min-height 300]
[stretchable-width #f]
[stretchable-height #f])
(super-new [min-width min-width]
[min-height min-height]
[stretchable-width stretchable-width]
[stretchable-height stretchable-height]))
不过,你是对的,这需要大量的打字和精细的代码来保持同步。类库中没有其他内置方式,但您可以通过一个小宏轻松添加一个:
(class canvas%
(define-syntax-rule (init/super-new [name default] ...)
(begin (init [name default] ...)
(super-new [name name] ...)))
(init/super-new
[min-width 600]
[min-height 300]
[stretchable-width #f]
[stretchable-height #f]))
define syntax rule
也可以很容易地在模块级执行,但是:
super new
。如果愿意,您当然可以支持这一点,但是,对于宏,您和库编写器都不必预先预见您可能需要的所有可能的便利。编写一个简单的宏,使您的特定代码更具可读性,这是完全合法的