Канонический способ сделать круговую зависимость в Nim
Предположим, у нас есть два модуля: один определяет Object, а другой определяет ObjectFactory. Объект должен иметь доступ к ObjectFactory и использовать некоторые из его функций, а ObjectFactory нужен доступ к Object, чтобы иметь возможность создавать экземпляры Objects.
Какой канонический способ решить эту проблему в Nim, если Object реализован в модуле, а ObjectFactory реализован в другом модуле?
1 ответ
Я предполагаю, что проблема здесь со взаимно рекурсивными типами, то есть где объявления двух или более типов ссылаются друг на друга. Методы или процедуры, которые ссылаются друг на друга, хорошо обрабатываются взаимно рекурсивным импортом, хотя в этом случае нужно быть осторожным с инициализацией модуля.
Как и в большинстве других языков, которые обычно требуют, чтобы взаимно-рекурсивные типы находились в одном модуле / модуле компиляции, существует два основных ответа.
Одним из решений является наличие двух типов в одном модуле, который импортируется как модулем, который объявляет тип объекта, так и модулем, который объявляет тип фабрики (оба типа все еще должны быть частью одного и того же предложения типа). Например, вы создаете отдельный файл, который называется factory_types.nim
и поместите в него оба типа:
type
ObjectFactory = ref object
lastValue: Object
x: proc(): Object
Object = ref object
factory: ObjectFactory
Этот модуль затем будет импортирован как модулем, реализующим объект, так и модулем, реализующим фабрику.
Другое решение, где вы можете хранить каждый тип в его модуле, - это параметрический полиморфизм, где параметр типа используется в качестве прямого объявления. Например, вы делаете:
type
ObjectFactory[TargetType] = ref object
lastValue: TargetType
generator: proc(): TargetType
и в других местах:
type
Object = ref object
factory: ObjectFactory[Object]