【问题标题】:Update the default value of a field with a mixin or inheritance使用 mixin 或继承更新字段的默认值
【发布时间】:2016-06-14 18:48:25
【问题描述】:

假设我有一些课程snack,有一个字段banana?

(define snack%
  (class object%
    (super-new)
    (init-field [banana? #f])))

这样做,我可以将我的snack% 构造成有banana?,或者没有,默认是没有banana?

(get-field banana? (new snack%))

(get-field banana? (new snack%
                        [banana? #f]))

(get-field banana? (new snack%
                        [banana? #t]))

评估为:

#f
#f
#t

正如预期的那样。

但是,现在我想构造一个snack-mixin 类,它采用snack% 类(或者实际上,任何具有banana? 字段的类),并将该字段的默认值更改为#t .

不幸的是,我似乎找不到修改继承类(如 mixin 中所定义)的默认值的方法。我无法修改它,然后在我调用super-new 之后set-field!,就像我在这里所做的那样:

(define (snack-mixin %)
  (class %
    (super-new)
    (set-field! banana? this #t)))

虽然这确实将默认值从 #f 更改为 #t

(get-field banana? (new (snack-mixin snack%))) ; => #t

它还具有忽略传递到banana? 字段中的任何内容并将其设置为#t 的负面影响:

(get-field banana? (new (snack-mixin snack%)
                        [banana? #f]))
    ; => #t

有什么办法可以制作一个 mixin,或者制作一个继承 snack% 的类,它保留相同的字段 banana?(如,不创建新字段),但在仍然让用户调用new时选择它?

【问题讨论】:

    标签: class object inheritance racket mixins


    【解决方案1】:

    您在那里使用的super-new 表单实际上可以接受参数,就像new 通常可以一样。所以只需创建自己的init 表单,构造一些默认为#tinternal-banana? 对象,然后将其传递给super-new,如下所示:

    (define (snack-mixin %)
      (class %
        (init [(internal-banana? banana?) #t])
        (super-new [banana? internal-banana?])))
    

    使用此版本的snack-mixin,您可以获得所需的行为,banana? 字段默认为#t,也可以设置为#f

    (get-field banana? (new (snack-mixin snack%)))
    
    (get-field banana? (new (snack-mixin snack%)
                            [banana? #f]))
    
    (get-field banana? (new (snack-mixin snack%)
                            [banana? #t]))
    

    评估为:

    #t
    #f
    #t
    

    正如预期的那样。

    编辑:正如 Asumu 指出的那样,您实际上不需要使用标识符 internal-banana?

    (define (snack-mixin %)
      (class %
        (init [banana? #t])
        (super-new [banana? banana?])))
    

    但是,这确实意味着您的类中的 banana? 变量和 banana? 字段将绑定到两个单独的变量。

    【讨论】:

    • 我认为您不需要额外的internal-banana? 重命名。这似乎工作得很好:(define (snack-mixin %) (class % (init [banana? #t]) (super-new [banana? banana?])))
    • 是的,虽然这看起来确实有缺点,banana?banana? 字段不喜欢同一件事。
    猜你喜欢
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多