rey*_*n64 8 dependency-injection scala traits cake-pattern
我想覆盖trait中的抽象类型<:而不是=(在这里回答Scala Upper Bounds:value不是type参数的成员).
我想用蛋糕模式,但这不起作用,我不明白为什么?
trait A {
def ping = println("ping")
}
trait Cake {
type T
}
trait S { this: Cake =>
type T = A
def t: T
t.ping
}
Run Code Online (Sandbox Code Playgroud)
好的,这个例子运行,但在我的实际用例中,我想覆盖类型<:而不是=.It似乎无法访问t函数,为什么?
trait S { this: Cake =>
type T <: A
def t: T
t.ping
}
Run Code Online (Sandbox Code Playgroud)
返回错误 value ping is not a member of S.this.T
Mar*_*sky 15
这是Scala类型系统的缺点.在确定mixin中的成员时,Scala使用两个规则:首先,具体总是覆盖抽象.第二,如果两个成员都是具体的,或者都是抽象的,那么后来以线性化顺序出现的那个成员获胜.
此外,自我类型的特征
trait S { this: C => ... }
Run Code Online (Sandbox Code Playgroud)
被隐含地增加到
trait S { this: S with C => ... }
Run Code Online (Sandbox Code Playgroud)
因此,特征S中的定义可以在S中访问.在您的情况下,特征S被视为:
trait S { this: S with Cake =>
type T = A
def t: T
t.ping
}
Run Code Online (Sandbox Code Playgroud)
现在,只要T具体就可以了,因为它会覆盖Cake中的抽象T.但是如果T是抽象的,那么Cake中的那个在线性化顺序中出现并获胜.而且T没有上限,所以没有成员ping.解决此问题的一种方法是通过编写以下内容来更改线性化顺序:
trait S { this: Cake with S =>
type T <: A
def t: T
t.ping
}
Run Code Online (Sandbox Code Playgroud)
如果Scala有一个不同的规则表明抽象类型成员的所有约束都在mixin中合并,而不是根据线性化顺序选择单个成员,那将更加清晰.这是我们将来要考虑的变化,但我们需要注意向后兼容性.
| 归档时间: |
|
| 查看次数: |
940 次 |
| 最近记录: |