2011-03-09 83 views
5

看一看下面的斯卡拉例如:为什么编译器不在外部类中查找方法?

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) 
    } 
} 
+0

请问这样的工作适合你吗? 类A { DEF FOO(X:智力):INT = X 私有类B扩展A { @Override DEF FOO():INT = FOO(3) } } – 2011-03-09 16:41:43

+1

@Rustem感谢,但我更感兴趣的是为什么规则是这样的而不是特定的解决方案(我已经通过使用自我类型注释已经有了一个很好的解决方案)。 – Jesper 2011-03-09 17:10:34

回答

10

技术上,B类是块。您可以将问题简化为以下内容:

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

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