Почему компилятор не ищет во включающем классе метод? - PullRequest
5 голосов
/ 09 марта 2011

Посмотрите на следующий пример 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 Ответ

10 голосов
/ 09 марта 2011

Технически класс B является блоком. Вы можете уменьшить проблему до следующего:

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

Это вызвало бы точно такую ​​же проблему. Он соответствует спецификациям, потому что все имена, введенные в тень блока, имеют одно и то же имя (игнорируя подпись, см. Главу 2 spec ). Перегрузка возможна только на уровне класса. (глава 6.26.3 в spec )

...