Ракетка: предварительное объявление интерфейса - PullRequest
2 голосов
/ 20 января 2020

Если у меня есть два интерфейса, определенных бок о бок, и я хотел бы иметь ссылки на каждый из них в другом контракте, то есть:

(define context-interface<%>
  (interface ()
    [entity-list (->m (listof (is-a?/c entity-interface<%>)))]
    )
  )

(define entity-interface<%>
  (interface ()
    [on-add (->m (is-a?/c context-interface<%>) void?)]
    )

, что я должен сделать, чтобы избежать ошибки cannot reference an identifier before its definition ? Я не нашел ничего похожего на предварительное объявление в C ++, означающее в документации по Racket. Из ответа на мой предыдущий вопрос я знаю, что можно как-то решить проблему, используя lazy-require, но что, если я хочу сохранить оба определения в одном исходном файле?

1 Ответ

2 голосов
/ 20 января 2020

Вы можете исправить этот тип ошибки «значение не инициализировано» в рекурсивных контрактах, добавив recursive-contract вокруг части контракта, чтобы отложить оценку этой части, пока она не понадобится. В этом случае вы можете добавить recursive-contract около (is-a?/c entity-interface<%>).

(define context-interface<%>
  (interface ()
    [entity-list (->m (listof (recursive-contract (is-a?/c entity-interface<%>))))]
    ))

(define entity-interface<%>
  (interface ()
    [on-add (->m (is-a?/c context-interface<%>) void?)]
    ))

Обратите внимание, что это может быть около (is-a?/c entity-interface<%>), потому что это стоимость контракта, но не может быть около просто entity-interface<%>, потому что это значение интерфейса ракетки / класса, а не контракт.

...