Encoders.product中的TypeTag是什么?

uh_*_*boi 1 scala implicit apache-spark apache-spark-sql

我使用Spark 2.1.1.

我从以下开始:

import org.apache.spark.sql.types._
val mySchema = StructType(
  StructField("id", IntegerType, true),
  StructField("code", StringType, false),
  StructField("value", DecimalType, false))
val myDS = Seq((1,"000010", 1.0), (2, "000020", 2.0)).as[mySchema]
Run Code Online (Sandbox Code Playgroud)

在这里,我看到mySchema不是一个类型,看了之后Encoders.scala我可以看到我需要通过这里传递一个Product的子类型

def product[T <: Product : TypeTag]: Encoder[T] = ExpressionEncoder()
Run Code Online (Sandbox Code Playgroud)

因此,在看到冒号操作符只是来自什么是Scala上下文和视图边界的隐式参数的语法糖之后,我可以看到应该有一个隐含的TypeTag [T]可用,但我不明白TypeTag [T]是如何隐含的SQLImplicits.scala.

   /**
   * @since 1.6.1
   * @deprecated use [[newSequenceEncoder]]
   */
  def newProductSeqEncoder[A <: Product : TypeTag]: Encoder[Seq[A]] = ExpressionEncoder() 
Run Code Online (Sandbox Code Playgroud)

即使它被弃用了,当我看到它时

 /** @since 2.2.0 */
  implicit def newSequenceEncoder[T <: Seq[_] : TypeTag]: Encoder[T] = ExpressionEncoder()
Run Code Online (Sandbox Code Playgroud)

我仍然想知道哪里有一个隐含声明的TypeTag [T]

Mik*_*nte 6

TypeTag是一个类型类,它将隐式加载您尝试召唤的任何类型的实例.这与Spark无关,或者SQLImplicits您可以尝试这样做

def getMyTypeTag[T : TypeTag]: TypeTag[T] = implicitly[TypeTag[T]]
Run Code Online (Sandbox Code Playgroud)

另一方面Encoder,一旦导入定义的implicits就可以通过spark构建spark sql SqlImplicits,如果你看一下就LowPrioritySQLImplicits可以看到你需要TypeTag创建Encoderfor Product(case类),这就是你需要加载的原因将TypeTag在隐式上下文

trait LowPrioritySQLImplicits {
  /** @since 1.6.0 */
  implicit def newProductEncoder[T <: Product : TypeTag]: Encoder[T] = Encoders.product[T]

}
Run Code Online (Sandbox Code Playgroud)

仅当您尝试召唤编码器的代码不是通用的或者TypeTag已经在上下文中时,才能召唤TypeTag.例如

def loadEncoder(): Encoder[MyType] ={
    import spark.implicits._
    Encoder[MyType] // The type is here so it will work
}
Run Code Online (Sandbox Code Playgroud)

另一方面

loadEncoder[MyType]
def loadEncoder[T](): Encoder[T] ={
    import spark.implicits._
    Encoder[T] // The type info is not here so it wont work
}
Run Code Online (Sandbox Code Playgroud)

loadEncoder[MyType]
def loadEncoder[T: TypeTag](): Encoder[T] ={
    import spark.implicits._
    Encoder[T] // The type info is not here but the TypeTag is so it will work
}
Run Code Online (Sandbox Code Playgroud)