2017-02-16 50 views
1

下面的代码并不编译:Scala编译器说: “可用于T号TypeTag” 的方法使用泛型

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 Generics发生了什么,编译器不是非常具体,任何想法?

+0

凡'Product'声明? – nmat

+0

它来自Scala(包scala) – italktothewind

回答

1

的问题是与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 */ } 
+0

我已经试过了,但是错误更糟: 错误:(11,24)javassist.bytecode.stackmap.TypeTag不带类型参数 def read [T <产品:TypeTag:NotNothing](collection:String):Dataset [T] = { 错误:(13,20)没有TypeTag可用于T mongoDbRdd.toDS [T] 错误:(13,20)方法toDS :(隐式证据$ 3:reflect.runtime.universe.TypeTag [T],隐式证据$ 4:com.mongodb.spark.NotNothing [T])org.apache.spark.sql.Dataset [T]。 未指定的值参数证明$ 3,证据$ 4。 mongoDbRdd.toDS [T] – italktothewind

+0

如果仔细查看错误消息,您会发现范围内存在错误的TypeTag类('javassist.bytecode.stackmap.TypeTag')。确保你正在导入'reflect.runtime.universe.TypeTag'。 – jkinkead

+0

就是这样,谢谢! – italktothewind