抽象型を使用すると、オーバーライドを検出するスカラーコンパイラの機能に影響し、一見正しいコードが誤っていると解釈されることがわかりました。抽象オーバーライドが失敗する理由
trait I {
type T
def doThings(t : T) : Unit
}
type IT[X] = I { type T = X}
trait A extends I {
override type T = AnyRef
def doThings(t : T) : Unit = println("A")
}
trait Z[X] extends I { this : IT[X] =>
abstract override def doThings(t : T) : Unit = {
println("Z")
super.doThings(t)
}
}
object Use {
val az = new A with Z[AnyRef] {}
}
Scalaのコンパイラ火災などのエラー:
OverloadAbstract.scala:44: error: object creation impossible, since method doThings in trait Z of type (t: this.T)Unit is marked `abstract' and `override', but no concrete implementation could be found in a base class
val az = new A with Z[AnyRef] {}
混合特性と実装の間のこのような関係を表現する適切な方法は何ですか?比較のために
は、そのコードが正常に動作します:ため
object PartialEventBus {
type ApplyEvent[E] = EventBus { type Event = E }
}
trait ForwardEventBus[E] extends EventBus { this : PartialEventBus.ApplyEvent[E] =>
def relay : PartialEventBus.ApplyEvent[E]
abstract override def publish(event : Event) : Unit = {
relay.publish(event)
super.publish(event)
}
}
種類のパラメータ化:
trait I {
def doThings() : Unit
}
class A extends I {
def doThings() : Unit = println("A")
}
trait Z extends I {
abstract override def doThings() : Unit = {
println("Z")
super.doThings()
}
}
object Use {
val az = new A with Z {}
}
実際のユースケースは、akka.event.EventBus
ためフォワーダを実装することですコンパイラがオブジェクト全体に一致するためにはForwardEventBus
が必要ですタイプは外部relay.Event
タイプです。コンパイラは、スカラのパスに依存する型の制限のために、そのようなヒントなしで失敗します。
自己型 'self:A =>'が働くので、 'T'が失われています。たぶん誰かが理由を言うことができます。トリッキーなので、抽象型のメンバで自己型を扱えるようにするには限界がありますが、ここではその理由はわかりません。 –