Прежде всего, ваш пример делает то, что вы, вероятно, не хотите.Использование init-field
создает изменяемое открытое поле для экземпляров вашего класса, которое инициализируется соответствующим аргументом инициализации.Они используются не очень часто: чаще используется закрытое поле (например, define
) и метод получения, возможно, с установщиком, если вы хотите поддерживать мутацию.Фактически, мы можем сказать, что, однако canvas%
использует эти аргументы инициализации, он не сохраняет их как открытые поля, поскольку (как и в случае с методами) класс не может создать новое поле с тем же внешним именем, что и полесвоего суперкласса.(Поля могут быть унаследованы с inherit-field
.) Например, при вычислении этого выражения возникает исключение:
(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
.Вы, конечно, можете поддержать это, если хотите, но с макросами ни вы, ни автор библиотеки не должны заранее предвидеть все возможные удобства, которые вы захотите.Полностью законно написать простой макрос, который сделает ваш конкретный код более читабельным.