簡體   English   中英

在scala中聲明父特征中的子特征的自我類型

[英]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有沒有辦法在父母特質中強制實施自我類型的兒童特質?

更新:看起來問題有點令人困惑。

我想要實現的是,我想省略為BookDbModuleAuthorDbModule設置自我類型的BookDbModule ,通過擴展(或任何其他scala特性)父特征DbModule同時具有自我類型DbConfig

所以,基本上,我正在尋找一種方法,通過在父DbModule聲明自我類型而不在那些子特征中,僅通過DbConfig的類來擴展子特征( BookDbModuleAuthorDbModule )。

// 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM