2015-10-16 88 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 –

相关问题