我有以下简单的代码,
public static IEnumerable<T[]> Buffer<T>(this IEnumerable<T> source, int count)
=>
source
.Select((t, i) => new { t, i })
.GroupBy(x => x.i / count)
.Select(x => x.Select(y => y.t).ToArray());
RDD [T]是不变的,因此RDD [Person]不是RDD [Product]的子类型,因此在最后一行中存在编译错误。
但我不理解第2行
case class Person(name: String, age: Int)
val sc: SparkContext = ...
val rdd: RDD[Product] = sc.parallelize(List(Person("a", 1), Person("b", 2))) //line 2
val rdd1 = sc.parallelize(List(Person("a", 1), Person("b", 2)))
val rdd2: RDD[Product] = rdd1 //compiling error
它是RDD [Person]类型,为什么可以将它分配给RDD [Product]?
答案 0 :(得分:2)
因为Scala中类型推断的一个非常重要的部分是期望类型。这些规则分散在https://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html上,但要解释这个具体案例:
第2行,
sc.parallelize(List(Person("a", 1), Person("b", 2)))
输入了预期类型RDD[Product]
,所以
List(Person("a", 1), Person("b", 2))
输入了预期类型List[Product]
,所以
Person("a", 1)
和Person("b", 2)
输入了预期类型Product
,并且此操作成功,因为Person
是Product
的子类型。
编译器插入类型参数
sc.parallelize[Product](List[Product](Person("a", 1), Person("b", 2)))
请注意,此RDD[Person]
永远不会出现在此过程中。即。
sc.parallelize(List(Person("a", 1), Person("b", 2)))
类型为RDD [Person]
不正确;它可以是这种类型,但在第2行它不是。
答案 1 :(得分:1)
从这里采取:https://www.scala-lang.org/api/2.12.x/scala/Product.html
所有产品的基本特征,标准库中包含at 至少scala.Product1通过scala.Product22因此也是他们的 子类scala.Tuple1到scala.Tuple22。此外,所有情况 classes使用综合生成的方法实现Product。
我能够运行你的代码:
import org.apache.log4j.{Level, Logger}
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession
object SparkSample {
object SparkSessionConf {
val LOCAL_MASTER = "local[*]"
}
def initializeSpark(master: String, appName: String): SparkSession = {
Logger.getLogger("org").setLevel(Level.ERROR)
SparkSession.builder
.master(master)
.appName(appName)
.getOrCreate()
}
case class Person(name: String, age: Int)
def main(args: Array[String]): Unit = {
val sparkSession = initializeSpark(SparkSessionConf.LOCAL_MASTER, "SparkTry")
val rdd: RDD[Product] = sparkSession.sparkContext.parallelize(List(Person("ss", 10), Person("ss", 20)))
val rdd1: RDD[Product] = sparkSession.sparkContext.parallelize(List(Person("ss", 10), Person("ss", 20)))
}
}
答案 2 :(得分:0)
Here是关于不变性的详细描述,并解释了为什么你不能将Person类强制转换为Product trait,尽管我们应该能够这样做。