2011-03-09 82 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)

相關問題