当我编译遵循代码之后IT失败并投掷错误时:
维护.scala:11:错误:读取方法的丢失参数列表 对象维护
object GenericTest {
def createStream[T: ClassTag](endpoint: String, shardId: Int, func: RecordEntry => T): DStream[T] = {
null
}
def createStream[T: ClassTag](endpoint: String,func: RecordEntry => T): DStream[T] = {
null
}
}
object MainTest {
def main(args: Array[String]): Unit = {
val ddd = GenericTest.createStream[String]("6", 1, read)
}
def read(record: RecordEntry): String = {
s"${record.getString(0)},${record.getString(1)}"
}
}
如果我删除了gentictest中的第二种方法Createstream,则维护可以成功编译。或者,如果我将维护的修改如下(call gentrictest.createstrem(xxx)时删除" [String]"),则可以成功编译。
def main(args: Array[String]): Unit = {
//remove the "[String]"
val ddd = GenericTest.createStream("6", 1, read)
}
或者如果我将维护段如下(将红色转换添加到func)进行修改,则可以成功编译。
def main(args: Array[String]): Unit = {
// add the " _" after read parameter
val ddd = GenericTest.createStream[String]("6", 1, read _)
}
对此问题有任何想法,为什么会汇总失败?正确的方法应该是什么样的?
错误是由于尝试将A 方法作为函数引起的。诸如read
之类的方法与对象关联,因此不能称为裸函数。
表达式read _
称为read
的ETA扩展,它基本上将MainTest
对象绑定到read
方法以创建裸函数。
因此,您已经有正确的方法在问题中的最后一个代码段中进行。
那么,如果只有一个createStream
的一个版本?
_
可以工作错误消息说:
未应用的方法仅在预期函数类型时转换为函数。
换句话说,如果您知道它需要函数时,编译器将通过方法自动进行此转换。
当createStream
有单个版本时,编译器可以将提供的值与该方法的参数匹配。它知道需要一个函数RecordEntry => T
,因此可以将转换(ETA扩展)从方法转换为函数。
当createStream
有多个超载版本时,编译必须首先确定要调用哪个版本。它将值的数量和类型与每个版本的createStream
的参数的数量和类型进行了比较。在这种情况下,func
没有匹配,因为类型是错误的:它是一种方法而不是函数。因此,当有超载方法时,您必须将方法转换为适当的超载方法匹配所需的类型。
编译错误说
Error:(25, 58) missing argument list for method read in object MainTest
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `read _` or `read(_)` instead of `read`.
val ddd = GenericTest.createStream[String]("6", 1, read)
所以请做
val ddd = GenericTest.createStream[String]("6", 1, read _)
或
val ddd = GenericTest.createStream[String]("6", 1, read(_))