我在DSL中遇到问题,重载泛型方法导致编译器希望我添加显式参数类型:
def alpha[T](fun: Int => T): String = fun(33).toString
def beta [T](fun: Int => T): String = fun(66).toString
def beta [T](thunk: => T): String = thunk.toString
alpha { _ + 11 } // ok
beta { _ + 22 } // "error: missing parameter type for expanded function"
beta { _: Int => _ + 22 } // ok... ouch.
我有机会摆脱最后一行的混乱吗?
修改
为了证明重载不是scalac本身的歧义问题,这里是一个没有类型参数的版本,它完全正常:
def beta(fun: Int => String): String = fun(66).reverse
def beta(thunk: => String): String = thunk.reverse
beta(_.toString) // ok
beta("gaga") // ok
答案 0 :(得分:4)
问题是Int => T
也是一种类型。例如,假设您只定义了第二个beta
:
def beta[ T ]( thunk: => T ) : String = thunk.toString
现在你将一个函数Int => Int
传递给它:
scala> beta((_: Int) + 1)
res0: String = <function1>
所以,假设一个函数适合=> T
,并且你也有一个Int => T
,那么Scala应该知道你想要哪一个?它可以是String
,例如:
scala> beta((_: String) + 11)
res1: String = <function1>
Scala如何假设它是Int
?你所展示的示例过载的例子不是责备不要展示任何这样的东西,因为你摆脱了它们中的类型参数。
答案 1 :(得分:1)
正如您可能已经意识到的那样,问题出现是因为您的beta函数已经过载。 定义时:
beta { _ + 22 }
你期望它打电话给哪个测试版? Scala无法知道_
只是Int
只是因为你用22求和它。所以对于这个特例,你必须定义_
是什么。