Scala内部类型作为抽象方法参数
在一些需要内部特征/类子类化的代码中,我很难成功实现抽象方法,显然是因为我的类型签名不匹配。例如:Scala内部类型作为抽象方法参数,scala,Scala,在一些需要内部特征/类子类化的代码中,我很难成功实现抽象方法,显然是因为我的类型签名不匹配。例如: trait Outer { trait Inner def score(i:Inner): Double } class Outer2 extends Outer { class Inner extends super.Inner def score(i:Inner) = 0.0 } 您可能会认为,Outer2.score没有成功实现Outer.score,因为类型Outer2.
trait Outer {
trait Inner
def score(i:Inner): Double
}
class Outer2 extends Outer {
class Inner extends super.Inner
def score(i:Inner) = 0.0
}
您可能会认为,Outer2.score
没有成功实现Outer.score
,因为类型Outer2.this.Inner
与Outer.this.Inner
不匹配。但是scala-2.9.0.1中的编译错误消息没有指出这一点。它说:
error: class Outer2 needs to be abstract, since method score in trait Outer
of type (i: Outer2.this.Inner)Double is not defined
(Note that Outer.this.Inner does not match Outer2.this.Inner)
它说它需要一个类型为Outer2.this.Inner
的参数!这正是我想要的行为。但是为什么我的第二个评分定义不能成功匹配抽象方法的类型呢
我试图用下面的替代代码让编译器更清楚,但我也得到了类似的令人困惑的错误消息
trait Outer[This<:Outer[This]] {
this: This =>
trait Inner
def score(i:This#Inner): Double
}
class Outer2 extends Outer[Outer2] {
class Inner extends super.Inner
def score(i:Outer2#Inner) = 0.0
}
trait-Outer[This]
特质内在
def分数(i:本#内):双倍
}
类Outer2扩展了Outer2[Outer2]{
类Inner扩展了super.Inner
def分数(i:外部2#内部)=0.0
}
无法在重写方法中优化方法参数的类型
这项工作:
class Outer2 extends Outer {
def score(i: super[Outer].Inner) = 0.0
// Or just:
// def score(i: super.Inner) = 0
}
考虑编译器是否允许您的代码:
trait Outer {
trait Inner
def score(i:Inner): Double
}
class Outer2 extends Outer {
class Inner extends super.Inner { def foo = "!" }
def score(i:Inner) = { i.foo; 0.0 }
// !!! unsafe, no `foo` method
score(new super[Outer].Inner{})
}
重写方法可能具有更具体的返回类型,因为这不会导致不健全的代码。(在JVM级别,返回类型包含在方法签名中,创建桥接方法以允许调用方根据超类中的签名编程并分派到子类中的实现。)无法在重写方法中优化方法参数的类型
这项工作:
class Outer2 extends Outer {
def score(i: super[Outer].Inner) = 0.0
// Or just:
// def score(i: super.Inner) = 0
}
考虑编译器是否允许您的代码:
trait Outer {
trait Inner
def score(i:Inner): Double
}
class Outer2 extends Outer {
class Inner extends super.Inner { def foo = "!" }
def score(i:Inner) = { i.foo; 0.0 }
// !!! unsafe, no `foo` method
score(new super[Outer].Inner{})
}
重写方法可能具有更具体的返回类型,因为这不会导致不健全的代码。(在JVM级别,返回类型包含在方法签名中,创建桥接方法以允许调用方根据超类中的签名编程并分派到子类中的实现。)这可能是一个合适的解决方案,具体取决于具体要求:
trait Outer {
trait InnerI
type Inner <: InnerI
def score(i:Inner): Double
}
class Outer2 extends Outer {
class InnerI extends super.InnerI
type Inner = InnerI
def score(i:Inner) = 0.0
}
trait-Outer{
内部性状
输入Inner这可能是一个合适的解决方法,具体取决于精确的要求:
trait Outer {
trait InnerI
type Inner <: InnerI
def score(i:Inner): Double
}
class Outer2 extends Outer {
class InnerI extends super.InnerI
type Inner = InnerI
def score(i:Inner) = 0.0
}
trait-Outer{
内部性状
输入Inner谢谢你的回答---这很有意义。但是,我仍然想知道为什么我的第二个代码块不起作用。顺便说一下,我发现编译器的错误消息非常令人困惑。它说缺少score(Outer2.this.Inner),而不是score(super[Outer].Inner)。也许这会改进错误诊断:谢谢你的回答---这很有意义。但是,我仍然想知道为什么我的第二个代码块不起作用。顺便说一句,我发现编译器的错误消息非常混乱。它说缺少score(Outer2.this.Inner),而不是score(super[Outer].Inner)。这可能会改进错误诊断: