2015-10-16 84 views
7

第一個例子成功地找到了隱式轉換的方法foo(String),但只要我添加一個類型參數(見fails)的編譯已經不解決這個問題:爲什麼Scala隱式解析失敗,因爲帶有類型參數的重載方法?

object works { 
    class A { 
    def foo(): String = ??? 
    } 
    implicit class PimpedA(a: A) { 
    def foo(i: String): String = ??? 
    } 
    val a = new A() 
    a.foo("test") //compiles 
} 

object fails { //same as `works`, but adds type parameter 
    class A { 
    def foo[T](): String = ??? 
    } 
    implicit class PimpedA(a: A) { 
    def foo[T](i: String): String = ??? 
    } 
    val a = new A() 
    PimpedA(a).foo("test") // compiles 
    a.foo("test") // error: too many arguments for method foo:()String 
} 

此行爲是相同的Scala 2.11.7和2.12.0-M3。

有關implicits的文檔似乎沒有涵蓋這一點,我沒有在stackoverflow上找到這個確切的案例。

請注意,我的目標是重載方法foo - 如果我重命名它,編譯器會找到它。

http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

+0

爲什麼你用同樣的名字'foo'來裝扮一個?也許這是顯而易見的,但如果你把它叫做'bar',錯誤不會顯示 –

+0

我知道,但我想重載'foo' - 我剛更新了這個問題。 –

回答

1

這兩種情況似乎在這種情況下the specification下跌:

視圖是在三種情況下應用:

...

在選擇e.m(args)e類型爲T,如果選擇器m表示某個成員,的T,但這些成員都不適用於參數args。在這種情況下,搜索v的視圖,該視圖適用於e,其結果包含適用於args的方法m。搜索過程與隱式參數一樣,其中隱式範圍是T之一。如果找到這樣的視圖,則將選擇e.m轉換爲v(e).m(args)

所以它應該工作。我真的很驚訝地看到它,因爲我從來沒有碰到過工作案例,並假設沒有隱含的搜索,如果T有任何成員m。我快速瀏覽了http://issues.scala-lang.org/,但找不到相關問題。

+0

謝謝阿列克謝。我在scala-lang jira上創建了一個問題:https://issues.scala-lang.org/browse/SI-9523 –

+0

typer debug output:https://gist.github.com/echojc/750ba177f88f4e81d2d0 –

相關問題