這是python的寫法:
可以看到同一個function,python不管丟進去的值是整數型態(Int),或是浮點數(Double)都可以自動判斷型別計算出結果.但是這件事在scala是無法做的.
def sum(x: Array[Int]) = {
x.reduce(_ + _)
}
sum(Array(1,2,3,4,5))
sum(Array(1.1,2.1,3.1,4.1,5.1))
由於在一開始就會指定輸入變項的型態,所以第二個sum會出現下面的編譯錯誤:Error:(8, 12) type mismatch;
found : Double(1.1)
required: Int
sum(Array(1.1,2.1,3.1,4.1,5.1))
^
要改採Match的寫法:
def sum(x: Any):Any = x match{
case y: Array[Int] => y.reduce(_ + _)
case y: Array[Double] => y.reduce(_ + _)
}
sum(Array(1,2,3,4,5))
res0: Any = 15
sum(Array(1.1,2.1,3.1,4.1,5.1))
res1: Any =15.5
但是這樣寫法並不能用在RDD上...
def sumRDD(x: Any):Any = x match{
case y: RDD[Int] => y.reduce(_ + _)
case y: RDD[Double] => y.reduce(_ + _)
}
會發生型態錯誤...warning: non-variable type argument Int in type pattern org.apache.spark.rdd.RDD[Int] is unchecked since it is eliminated by erasure
warning: non-variable type argument Double in type pattern org.apache.spark.rdd.RDD[Double] is unchecked since it is eliminated by erasure
紅字的地方代表說當東西丟到RDD裡面,不管是Int還是Double,都已經被抹除(erasure)了從外面都已經認不出來那是什麼東西了...(就是個黑箱!)所以也無法靠著match-case來選擇處理輸入物件的方式.
未來如果要處理這樣的問題(不同輸入型態,但是功能相同),就要回到標準物件導向多型的寫法,在一個物件下面定義不同的方法,每個方法使用相同的命名,但是不同的輸入物件型態來區分.
沒有留言:
張貼留言