Encoders.product 中的 TypeTag 是什么?
What is TypeTag in Encoders.product?
我用的是 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]
在这里我看到 mySchema 不是一个类型,在查看 Encoders.scala
之后我可以看到我需要通过
在此处传递 Product 的子类型
def product[T <: Product : TypeTag]: Encoder[T] = ExpressionEncoder()
所以在看到冒号运算符只是来自 What are Scala context and view bounds? 的隐式参数的语法糖之后,我可以看到应该有一个隐式的 TypeTag[T]可用,但我不明白 TypeTag[T] 是如何从 SQLImplicits.scala
.
中隐含的
/**
* @since 1.6.1
* @deprecated use [[newSequenceEncoder]]
*/
def newProductSeqEncoder[A <: Product : TypeTag]: Encoder[Seq[A]] = ExpressionEncoder()
尽管它已被弃用,但当我查看
/** @since 2.2.0 */
implicit def newSequenceEncoder[T <: Seq[_] : TypeTag]: Encoder[T] = ExpressionEncoder()
我仍然想知道哪里有隐式声明的TypeTag[T]?
TypeTag
是一种类型 class,它将隐式加载您尝试召唤的任何类型的实例。这独立于 Spark 或 SQLImplicits
,例如你可以试试这个
def getMyTypeTag[T : TypeTag]: TypeTag[T] = implicitly[TypeTag[T]]
另一方面,只要您导入 SqlImplicits
中定义的隐含函数,就可以通过 spark 构建一个 spark sql Encoder
,如果您查看 [=19] =] 你可以看到你需要 TypeTag
来为 Product
创建 Encoder
(案例 classes),这就是你需要加载 TypeTag
的原因在隐式上下文中
trait LowPrioritySQLImplicits {
/** @since 1.6.0 */
implicit def newProductEncoder[T <: Product : TypeTag]: Encoder[T] = Encoders.product[T]
}
仅当您尝试调用编码器的代码不是通用代码或 TypeTag 已在上下文中时,才能调用 TypeTag。例如
def loadEncoder(): Encoder[MyType] ={
import spark.implicits._
Encoder[MyType] // The type is here so it will work
}
另一方面
loadEncoder[MyType]
def loadEncoder[T](): Encoder[T] ={
import spark.implicits._
Encoder[T] // The type info is not here so it wont work
}
和
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
}
好吧,我以为是 Spark 的东西,但是页面顶部有一个 import 语句
import scala.reflect.runtime.universe.TypeTag
当我查看 API 页面时 http://www.scala-lang.org/api/2.11.6/scala-reflect/index.html#scala.reflect.api.TypeTags 我可以看到这里正在处理它。
我用的是 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]
在这里我看到 mySchema 不是一个类型,在查看 Encoders.scala
之后我可以看到我需要通过
def product[T <: Product : TypeTag]: Encoder[T] = ExpressionEncoder()
所以在看到冒号运算符只是来自 What are Scala context and view bounds? 的隐式参数的语法糖之后,我可以看到应该有一个隐式的 TypeTag[T]可用,但我不明白 TypeTag[T] 是如何从 SQLImplicits.scala
.
/**
* @since 1.6.1
* @deprecated use [[newSequenceEncoder]]
*/
def newProductSeqEncoder[A <: Product : TypeTag]: Encoder[Seq[A]] = ExpressionEncoder()
尽管它已被弃用,但当我查看
/** @since 2.2.0 */
implicit def newSequenceEncoder[T <: Seq[_] : TypeTag]: Encoder[T] = ExpressionEncoder()
我仍然想知道哪里有隐式声明的TypeTag[T]?
TypeTag
是一种类型 class,它将隐式加载您尝试召唤的任何类型的实例。这独立于 Spark 或 SQLImplicits
,例如你可以试试这个
def getMyTypeTag[T : TypeTag]: TypeTag[T] = implicitly[TypeTag[T]]
另一方面,只要您导入 SqlImplicits
中定义的隐含函数,就可以通过 spark 构建一个 spark sql Encoder
,如果您查看 [=19] =] 你可以看到你需要 TypeTag
来为 Product
创建 Encoder
(案例 classes),这就是你需要加载 TypeTag
的原因在隐式上下文中
trait LowPrioritySQLImplicits {
/** @since 1.6.0 */
implicit def newProductEncoder[T <: Product : TypeTag]: Encoder[T] = Encoders.product[T]
}
仅当您尝试调用编码器的代码不是通用代码或 TypeTag 已在上下文中时,才能调用 TypeTag。例如
def loadEncoder(): Encoder[MyType] ={
import spark.implicits._
Encoder[MyType] // The type is here so it will work
}
另一方面
loadEncoder[MyType]
def loadEncoder[T](): Encoder[T] ={
import spark.implicits._
Encoder[T] // The type info is not here so it wont work
}
和
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
}
好吧,我以为是 Spark 的东西,但是页面顶部有一个 import 语句
import scala.reflect.runtime.universe.TypeTag
当我查看 API 页面时 http://www.scala-lang.org/api/2.11.6/scala-reflect/index.html#scala.reflect.api.TypeTags 我可以看到这里正在处理它。