[英]Declare self-type of a child trait in a parent trait in scala
我有一些具有相同自我类型的scala特征,如下所示。
trait BookDbModule {
self: DbConfig => // Abstract this to a parent trait
/* ... */
}
trait AuthorDbModule {
self: DbConfig => // Abstract this to a parent trait
/* ... */
}
我试图将自我类型声明抽象为父特征,使得这些特征中的每一个都不必定义自我类型。 我尝试了以下内容。
trait DbModule {
self: DbConfig =>
// Some common DbModule methods
}
// !!! Illegal Inheritance, self-type BookDbModule does not conform to DbConfig
trait BookDbModule extends DbModule {
// What needs to be used instead of extends?
/* ... */
}
// !!! Illegal Inheritance, self-type AuthorDbModule does not conform to DbConfig
trait AuthorDbModule extends DbModule {
// What needs to be used instead of extends?
/* ... */
}
错误消息Illegal Inheritance
对我有意义,因为BookDbModule
不扩展DbConfig
。
Scala有没有办法在父母特质中强制实施自我类型的儿童特质?
更新:看起来问题有点令人困惑。
我想要实现的是,我想省略为BookDbModule
和AuthorDbModule
设置自我类型的BookDbModule
,通过扩展(或任何其他scala特性)父特征DbModule
同时具有自我类型DbConfig
。
所以,基本上,我正在寻找一种方法,通过在父DbModule
声明自我类型而不在那些子特征中,仅通过DbConfig
的类来扩展子特征( BookDbModule
和AuthorDbModule
)。
// This works but is there any way to omit necessity to write
// self: DbConfig =>
trait AuthorDbModule extends DbModule {
self: DbConfig =>
/* ... */
}
如果它仍然令人困惑,请告诉我。
谢谢!
看看这个:
scala> trait DbConfig { def f = 123 }
defined trait DbConfig
DbModule
需要DbConfig
实现:
scala> trait DbModule { self: DbConfig => }
defined trait DbModule
BookDbModule
的类型为DbModule
,仍然需要DbConfig
实现:
scala> trait BookDbModule extends DbModule { self: DbConfig => }
defined trait BookDbModule
scala> new BookDbModule with DbConfig {}.f
res0: Int = 123
BookDbModule
的类型为BookDbModule
,需要直接实现DbConfig
:
scala> trait BookDbModule { self: DbConfig => }
defined trait BookDbModule
scala> new BookDbModule with DbConfig {}.f
res1: Int = 123
BookDbModule
的类型为BookDbModule
,需要DbModule
实现,而这又需要DbConfig
实现:
scala> trait BookDbModule { self: DbModule => }
defined trait BookDbModule
scala> new BookDbModule with DbConfig {}.f
<console>:14: error: illegal inheritance;
self-type BookDbModule with DbConfig does not conform to BookDbModule's selftype BookDbModule with DbModule
new BookDbModule with DbConfig {}.f
^
scala> new BookDbModule with DbConfig with DbModule {}.f
res3: Int = 123
您还可以使用继承:
trait BookDbModule extends DbModule with DbConfig
scala> new BookDbModule with DbConfig {}.f
res4: Int = 123
但是, 您无法以某种方式继承自我类型注释 ,因此您可以使用继承,也可以显式注释自身类型。 请注意,这种简化也是可能的:
scala> trait DbConfig { def f = 123 }
defined trait DbConfig
scala> trait DbModule { self: DbConfig => }
defined trait DbModule
scala> trait DbModuleService extends DbModule with DbConfig
defined trait DbModuleService
最接近你要找的东西,但必须使用“完整”的中间特性DbModuleService
:
scala> trait BookDbModule extends DbModuleService
defined trait BookDbModule
scala> new BookDbModule {}.f
res0: Int = 123
要么:
scala> trait DbConfig { def f = 123 }
defined trait DbConfig
scala> trait DbModule { self: DbConfig => }
defined trait DbModule
scala> trait DbModuleService extends DbModule with DbConfig
defined trait DbModuleService
scala> trait BookDbModule { self: DbModuleService => }
defined trait BookDbModule
scala> new BookDbModule with DbModuleService {}.f
res0: Int = 123
答案是不。 这不可能。 事实上你所说的是违背自我打字的目的。
trait DbModule {
self: DbConfig =>
}
trait BookDbModule extends DbModule {
}
在你的例子中(这里总结), DbModule
说我的孩子必须以某种方式提供DbConfig
定义的功能。 但特质BookDbModule
无法显示,除非它扩展DbConfig
或显式自我键入它。 这是违背你想要的......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.