Scala 编译器在使用泛型的方法中显示 "No TypeTag available for T"

标签 scala generics methods types

以下代码未编译:

override def read[T <: Product](collection : String): Dataset[T] = {
  val mongoDbRdd = MongoSpark.load(sparkSession.sparkContext,MongoDBConfiguration.toReadConfig(collection))
  mongoDbRdd.toDS[T]
}

这是“toDS”的定义:
def toDS[T <: Product: TypeTag: NotNothing](): Dataset[T] = mongoSpark.toDS[T]()

编译器说:
Error:(11, 20) No TypeTag available for T
    mongoDbRdd.toDS[T]

Error:(11, 20) not enough arguments for method toDS: (implicit evidence$3: reflect.runtime.universe.TypeTag[T], implicit evidence$4: com.mongodb.spark.NotNothing[T])org.apache.spark.sql.Dataset[T].
Unspecified value parameters evidence$3, evidence$4.
    mongoDbRdd.toDS[T]

第 11 行是 mongoDbRdd.toDS[T]
我真的不知道 Scala 泛型发生了什么,而且编译器不是很具体,有什么想法吗?

最佳答案

问题在于 T 上的类型约束那个toDS要求:

// The ':' constraint is a type class constraint.
def toDS[T <: Product: TypeTag: NotNothing](): Dataset[T] =
  mongoSpark.toDS[T]()

// The below is exactly the same as the above, although with user-defined
// names for the implicit parameters.
// All a type class does is append implicit parameters to your function.
def toDS[T <: Product]()(implicit typeTag: TypeTag[T], notNothing: NotNothing[T]) =
  mongoSpark.toDS[T]()

您会注意到这就是您的编译器错误显示的内容 - 名称扩展为 evidence$3evidence$4 .

如果您希望您的方法编译,只需添加相同类型的类:
override def read[T <: Product: TypeTag: NotNothing](
    collection : String): Dataset[T] = { /* impl */ }

关于Scala 编译器在使用泛型的方法中显示 "No TypeTag available for T",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42285560/

相关文章:

scala - 如何防止编译器选择最少泛型类型?

scala - 类路径中缺少符号 'type cats.MonadFilter'

generics - 通用自定义运算符函数 : A Curious Case of a Bad * Instruction

java - 通用数组作为参数

c++ - 成员方法必须使用的帮助函数在哪里/如何声明和实现?

scala - 什么是微服务回归套件的最佳方法,Scala 可以用于此吗?

c# - lambda 中的类型推断

java - 如何在 Android/Java 中以不同的方式传递参数?

java - 另一个类中的 SQL 更新

scala - 从宏中获取具有匿名类方法的结构类型