使用Scala通用参数编译故障



当我编译遵循代码之后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(_))

最新更新