使用scala泛型参数编译失败

muk1a3rh  于 2021-07-14  发布在  Java
关注(0)|答案(2)|浏览(405)

当我编译以下代码时,它会失败并抛出错误:
主测试。scala:11:错误:对象maintest中读取的方法缺少参数列表

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)}"
  }
}

如果我删除generictest中的第二个方法createstream,那么maintest可以成功编译。或者,如果我修改maintest如下(在调用generictest.createstrem()时删除“[string]”,它可以成功编译。

def main(args: Array[String]): Unit = {
    //remove the "[String]"
    val ddd = GenericTest.createStream("6", 1, read)
  }

或者,如果我修改maintest如下(添加红色convert to func),它可以成功编译。

def main(args: Array[String]): Unit = {
    // add the " _" after read parameter
    val ddd = GenericTest.createStream[String]("6", 1, read _)
  }

你知道这个问题吗,为什么会失败?正确的方法应该是什么样的?

mfuanj7w

mfuanj7w1#

该错误是由于尝试将方法作为函数传递引起的。一种方法,如 read ,与对象相关联,因此不能将其作为裸函数调用。
表达式 read _ 被称为eta的扩展 read 它基本上把 MainTest 反对 read 方法来创建裸函数。
所以在问题的最后一段代码中已经有了正确的方法。
那么,为什么它在没有 _ 如果只有一个版本 createStream ?
错误消息显示:
只有在需要函数类型时,未应用的方法才会转换为函数。
换言之,如果您在一个方法知道它需要函数时传递该方法,编译器将自动执行此转换。
当有单一版本的 createStream 编译器可以将提供的值与该方法的参数匹配。它知道一个函数 RecordEntry => T 是必需的,因此它执行从方法到函数的转换(eta展开)。
当有多个重载版本的 createStream 编译程序必须首先确定调用哪个版本。它将值的数量和类型与每个版本的参数的数量和类型进行比较 createStream . 在这种情况下,没有对手 func 因为类型是错误的:它是一个方法而不是一个函数。因此,当存在重载方法时,必须将该方法转换为相应重载方法所需的类型。

6jjcrrmo

6jjcrrmo2#

编译错误说明

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(_))

相关问题