简体   繁体   English

Encoders.product中的TypeTag是什么?

[英]What is TypeTag in Encoders.product?

I use Spark 2.1.1. 我使用Spark 2.1.1。

I started off with the following: 我从以下内容开始:

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]

Here I saw that mySchema was not a type and after looking at Encoders.scala I could see I needed to pass a subtype of Product here via 在这里,我看到mySchema不是类型,在查看了Encoders.scala之后,我看到我需要通过此处传递Product的子类型

def product[T <: Product : TypeTag]: Encoder[T] = ExpressionEncoder()

So after seeing that the colon operator is just syntactical sugar for an implicit parameter from What are Scala context and view bounds? 因此,在从什么是Scala上下文边界和视图边界看到冒号运算符只是隐式参数的语法糖之后 , I can see that there should be an implicit TypeTag[T] available but I don't understand though how TypeTag[T] is implicit from looking at SQLImplicits.scala . ,我可以看到应该有一个隐式TypeTag [T] ,但是我从SQLImplicits.scala看,虽然我不理解TypeTag [T]是如何隐式的。

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

Even though it's deprecated, when I look at 即使已弃用,当我看着

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

I still wonder where is there a TypeTag[T] implicitly declared? 我仍然想知道在哪里隐式声明了TypeTag [T]

TypeTag is a type class that will implicitly load an instance for any type you try to summon. TypeTag是一个类型类,它将为您尝试TypeTag任何类型隐式加载实例。 This is independent from Spark or SQLImplicits , for example you can try this 这独立于Spark或SQLImplicits ,例如,您可以尝试此

def getMyTypeTag[T : TypeTag]: TypeTag[T] = implicitly[TypeTag[T]]

On the other hand a spark sql Encoder can be built by spark as soon as you import the implicits defined in SqlImplicits , if you take a look to LowPrioritySQLImplicits you can see that you need the TypeTag to create the Encoder for Product (case classes), that's why you need to load the TypeTag in the implicit context 另一方面,只要导入SqlImplicits定义的隐式,就可以由spark构建spark sql Encoder 。如果查看LowPrioritySQLImplicits您会发现需要TypeTag来创建ProductEncoder (案例类),这就是为什么您需要在隐式上下文中加载TypeTag

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

}

The TypeTag can be summoned only if the code from where you are trying to summon the Encoder is not generic or the TypeTag is already in the context. 仅当您尝试从中调用编码器的代码不是通用的或上下文中已经存在TypeTag时,才能调用TypeTag。 For Example 例如

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

on the other hand 另一方面

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

and

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
}

Ok I thought it was a Spark thing, but there is an import statement at the top of the page 好的,我认为这是Spark的事情,但是页面顶部有一个import语句

import scala.reflect.runtime.universe.TypeTag

When I look at the API page http://www.scala-lang.org/api/2.11.6/scala-reflect/index.html#scala.reflect.api.TypeTags I can see it's being handled here. 当我查看API页面http://www.scala-lang.org/api/2.11.6/scala-reflect/index.html#scala.reflect.api.TypeTags时 ,可以看到它在这里处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM