[英]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.