我正在尝试为我的应用程序设计一个小型模块系统,以便我可以做到这一点:
new MyApplication extends Module1 with Module2 ... with ModuleN
为了让我的模块能够在应用程序中注册自己,我还需要:
trait ModuleRegistry {
def register(start: () => Unit) = // Stores start functions in a list
}
trait Module {
self: ModuleRegistry =>
self.register(start)
def start(): Unit
}
class Application extends ModuleRegistry {
}
trait Module1 extends Module {
...
}
这个想法是,模块可以在注册表中注册一个函数,当应用程序启动时调用该函数。不幸的是,Scala 编译器强制我这样做:
trait Module1 extends Module {
self: ModuleRegistry =>
}
意味着所有模块的实现都必须在注册表中明确指定自身类型,而理想情况下它们不应该知道它。
那么我的问题是:
1. 为什么编译器要求我在扩展特质时重新指定这个 self-type?理想情况下,我甚至不希望扩展特质“看到”这个类型,因为它应该由基础模块特质处理。这个“具体”的模块应该由第三方实现,所以向他们公开注册表似乎有点丑陋。 2. 在 Scala 中是否有更好的方法来实现我正在尝试实现的目标,以便可以自由地混合模块?
Module1
和Module2
都定义了start
... - Rex Kerr