下面我有两段代码。第一个编译得很好:
object StackOverflow {
class TwoMethods {
def setString(string: String): Unit = {}
def setLong(long: Long): Unit = {}
}
def populate[T](f: T => Unit, value: Option[Any]): Unit = {
value.foreach(x => f(x.asInstanceOf[T]))
}
def someMethod(twoMethods: TwoMethods): Unit = {
populate(twoMethods.setString, Some("string"): Option[Any])
populate(twoMethods.setLong, None: Option[Long])
}
}
但是,如果 populate 方法被重载,那么编译器会要求我将下划线添加到未应用的方法,以便转换为函数工作(以下不编译):
object StackOverflow {
class TwoMethods {
def setString(string: String): Unit = {}
def setLong(long: Long): Unit = {}
}
def populate[T](f: T => Unit, value: Option[T]): Unit = {
value.foreach(f(_))
}
def populate[X: ClassTag](f: String => Unit, value: Option[Any]): Unit = {
value.foreach(x => f(x.toString))
}
def someMethod(twoMethods: TwoMethods): Unit = {
populate(twoMethods.setString, Some("string"): Option[Any])
populate(twoMethods.setLong, None: Option[Long])
}
}
它要我改变它以便工作:
...
populate(twoMethods.setString _, Some("string"): Option[Any])
populate(twoMethods.setLong _, None: Option[Long])
...
为什么会发生这种情况?如何避免在每个 populate 调用的第一个参数中添加下划线?
答案 0 :(得分:3)
编译器必须具有关于参数的类型信息,以便解决重载方法。因此,当它查看重载方法的参数时,它没有“预期类型”信息。这就是它抱怨Unapplied methods are only converted to functions when a function type is expected.
现在,你和我都知道每个重载方法都需要一个函数,但是编译器不会尝试交错这两个步骤(也许搜索空间中可能存在组合爆炸?)。
我认为你避免这种情况的唯一选择就是超载。