为什么编译器不查看方法的封闭类?

时间:2011-03-09 15:42:54

标签: scala methods compiler-errors

查看以下Scala示例:

class A {
  def foo(x: Int): Int = x

  private class B {
    def foo(): Int = foo(3)
  }
}

编译时,编译器会生成错误消息:

A.scala:5: error: too many arguments for method foo: ()Int
                def foo(): Int = foo(3)
                                    ^

由于某种原因,编译器不查看封闭类A来查找要调用的方法。它只在类B中查找,找到那里没有参数的foo方法,然后放弃。如果我重命名方法,那么它没有问题:

class A {
  def bar(x: Int): Int = x

  private class B {
    def foo(): Int = bar(3)
  }
}

在这种情况下,编译器会查找类A并在那里找到bar方法。

为什么第一个例子不起作用;这是根据Scala的规范,还是这是一个编译器错误?如果这是根据规则,那么为什么规则是这样的?

顺便说一下,解决问题的另一种方法是使用自我类型注释:

class A {
  self =>

  def foo(x: Int): Int = x

  private class B {
    def foo(): Int = self.foo(3)
  }
}

1 个答案:

答案 0 :(得分:10)

从技术上讲,B类是一个块。您可以将问题减少到以下内容:

def foo(x: Int): Int = x;
{    
   def foo(): Int = foo(3)
}

这会导致完全相同的问题。它符合规范,因为块中引入的所有名称都会影响任何具有相同名称的名称(忽略签名,请参阅spec的第2章)。只能在课程级别进行重载。 (spec中的第6.26.3章)