Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala内部类型作为抽象方法参数_Scala - Fatal编程技术网

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)。这可能会改进错误诊断: