Это может показаться похожим на вопросы типа Перегрузка конструктора структуры? или Перегрузка конструктора структуры . Но ни один из этих вопросов не решает проблему передачи перегруженного идентификатора за пределы модуля (путем его предоставления).
Например, допустим, у меня есть структура, я хочу перегрузить конструктор:
(struct fish (weight scales))
(define (make-fish [weight 5] [scales 'blue])
(fish weight scales))
Теперь я хочу предоставить новый конструктор, чтобы он имел имя структуры, чтобы сделать его использование полностью прозрачным:
(provide
(except-out (struct-out fish) fish)
(rename-out (make-fish fish)))
Это будет работать большую часть времени. Но есть небольшие тонкие ошибки, которые могут возникнуть.
Наследование структуры больше невозможно, равно как и использование match
:
(require animals/fish)
(struct shark fish (teeth)) ;; ERROR: parent struct type not defined
(define (describe-animal animal)
(match animal
[(fish weight scales) ;; ERROR: syntax error in pattern
(format "A ~a pounds fish with ~a scales" weight scales)]
[_ "Not a fish"]))
Сбой: использование расширителя совпадений
Создание расширителя матча (принятое решение в связанных вопросах).
Это не сработает, потому что вы не можете экспортировать расширитель совпадений в виде структуры.
#lang racket/base
(require
(for-syntax
racket/base
syntax/transformer)
racket/match)
(provide
(except-out (struct-out fish) fish)
(rename-out (make-fish fish)))
(struct fish (weight scales)
#:name private-fish
#:constructor-name private-fish)
(define (make-fish [weight 5] [scales 'blue])
(private-fish weight scales))
(define-match-expander fish
(lambda (stx)
(syntax-case stx ()
[(_ field ...) #'(private-fish field ...)]))
(make-variable-like-transformer #'private-fish))
Вы получаете ошибку:
struct-out: идентификатор не связан с информацией о типе структуры
по адресу: рыба
в: (структурированная рыба)
Вопрос
Итак, как мы можем изменить конструктор структуры, но при этом разрешить ее предоставление и использование в качестве родителя в других структурах?