在 Nim 中进行循环依赖的规范方式

Cannonical way to do circular dependency in Nim

假设我们有两个模块:一个定义了一个Object,一个定义了一个ObjectFactory。 Object 需要访问 ObjectFactory 使用它的一些功能,而 ObjectFactory 需要访问 Object 才能实例化 Objects。

如果 Object 在一个模块中实现而 ObjectFactory 在另一个模块中实现,在 Nim 中解决这个问题的规范方法是什么?

我假设这里的问题与相互递归类型有关,即两个或多个类型的声明相互引用。相互引用的方法或过程可以通过相互递归导入很好地处理,尽管在这种情况下必须小心模块初始化。

与大多数其他通常要求相互递归类型位于同一 module/compilation 单元内的语言一样,有两个主要答案。

一种解决方案是将两种类型放在同一个模块中,该模块由声明对象类型的模块和声明工厂类型的模块导入(两种类型仍需要属于同一类型子句).例如,您创建一个单独的文件,名称类似于 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]