本篇文章為大家展示了如何進行scala隱式轉(zhuǎn)換及Spark源碼解析,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
十載專注成都網(wǎng)站制作,成都定制網(wǎng)站,個人網(wǎng)站制作服務(wù),為大家分享網(wǎng)站制作知識、方案,網(wǎng)站設(shè)計流程、步驟,成功服務(wù)上千家企業(yè)。為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計及定制高端網(wǎng)站建設(shè)服務(wù),專注于成都定制網(wǎng)站,高端網(wǎng)頁制作,對成都格柵板等多個領(lǐng)域,擁有豐富的營銷推廣經(jīng)驗。
隱式轉(zhuǎn)換,是scala當(dāng)中一個重要的特性,今天我們結(jié)合自己的例子和spark源碼,爭取對隱式轉(zhuǎn)換有一個更加深入的了解。
關(guān)于implicit有3種使用方式,implicit def、implicit class以及implicit 參數(shù)
首先看一下implicit def的用法:
object implicitTest {
class Man(val name: String){
def work(){println(name + " is working!")}
}
class Woman(val name: String){
def shop(){println(name + " is shopping!")}
}
class Child(val name: String){
def play(){println(name + " is playing!")}
}
implicit def manToWoman(man: Man) = new Woman(man.name)
implicit def manToChild(man: Man) = new Child(man.name)
def main(args: Array[String]): Unit ={
val man = new Man("Tom")
val woman = new Woman("Lily")
val child = new Child("baby")
man.work()
man.shop()
man.play()
}
}
在上面的代碼當(dāng)中,我們定義了3個class,Man、Woman、Child,他們之間沒有任何繼承關(guān)系。下面的main函數(shù)當(dāng)中,我們聲明了Man、Woman、Child,各一個實例,我們考慮,作為男人來講,是不是也不一定只能是工作,適當(dāng)?shù)男蓍e和娛樂是不是也是可以的。所以我們做了2個隱式轉(zhuǎn)換的函數(shù),manToWoman和manToChild,需要注意的是,這兩個函數(shù)名其實一點都不重要,我們只是希望看起來更容易理解一些,你寫個aaa或者bbb,一點問題都沒有。
編譯過程大概是這樣的:
1、編譯man.shop(),發(fā)現(xiàn)并沒有shop方法,即將報錯
2、報錯之前,搜索一下作用域內(nèi),有沒有隱式轉(zhuǎn)換函數(shù),能夠支持man對shop的調(diào)用,找到了manToWoman。
3、把man變成woman,調(diào)用shop方法
之后再看一下implicit class的用法:
object implicitTest {
class Man(val name: String){
def work(){println(name + " is working!")}
}
class Woman(val name: String){
def shop(){println(name + " is shopping!")}
}
class Child(val name: String){
def play(){println(name + " is playing!")}
}
implicit class ManConvert(m: Man){
def shop() = new Woman(m.name).shop()
def play() = new Child(m.name).play()
}
def main(args: Array[String]): Unit ={
val man = new Man("Tom")
val woman = new Woman("Lily")
val child = new Child("baby")
man.work()
man.shop()
man.play()
}
}
這個當(dāng)中實現(xiàn)的效果看起來和前一種差不多,其實它的語義是完全不同的。編譯過程大概是這樣的:
1、編譯man.shop(),發(fā)現(xiàn)并沒有shop方法,即將報錯
2、報錯之前,搜索一下作用域內(nèi),看看有沒有隱式轉(zhuǎn)換類,能夠為man提供shop方法,找到了ManConvert
3、將man轉(zhuǎn)換為ManConvert,執(zhí)行shop方法。
最后我們再看一下implicit參數(shù)的用法:
object implicitTest {
class Man(val name: String){
def work(){println(name + " is working!")}
def marry(implicit w: Woman){println(name + " marryed " + w.name)}
}
class Woman(val name: String){
def shop(){println(name + " is shopping!")}
}
def main(args: Array[String]): Unit ={
val man = new Man("Tom")
implicit val woman = new Woman("Lily")
man.marry
}
}
我們?yōu)镸an增加了一個marry的方法,它的參數(shù)w是implicit的,然后調(diào)用的時候,我們先在前面聲明了一個implicit 類型的woman,之后調(diào)用marry但是不指定參數(shù),這樣是不會報錯得到。但是如果我們在marry的前面聲明了2個implicit的woman,那么marry還是會報錯的。
換成人類的語言來解釋這件事:一個男人要結(jié)婚,如果指定結(jié)婚對象,那沒問題,如果沒指定,那就看看身邊有沒有適合的結(jié)婚對象,有的話,就直接生米煮成熟飯,可是如果身邊有2個,好吧,我也不知道該娶哪個!
結(jié)合Spark源碼,我們來深入理解一下implicit,看下面這段代碼:
val rdd = sc.textFile("hdfs://master:9000/woozoom/mavlink1.log", 12).zipWithIndex()
rdd.sortByKey()
看起來是達到目的了,可是這個sortByKey的確切含義究竟是什么,倒序?正序?能不能自定義排序原則?去找一下spark的api文檔吧,找到RDD類,查找sortByKey方法,可是,居然,居然沒有,只有sortBy,沒有sortByKey。懵逼了~~~~~~
直到我了解了implicit這回事,并且在RDD的源碼當(dāng)中我們找到了下面這段:
implicit def rddToOrderedRDDFunctions[K : Ordering : ClassTag, V: ClassTag](rdd: RDD[(K, V)])
: OrderedRDDFunctions[K, V, (K, V)] = {
new OrderedRDDFunctions[K, V, (K, V)](rdd)
}
上面我們對scala的implicit做了比較全面的了解,這樣的工作,對scala和spark的學(xué)習(xí)和理解,非常重要。
但是,我要說但是,凡事都有其兩面性,implicit在帶來代碼的緊湊和精煉的同時,負作用就是可讀性極差;特別是在工作的初級階段,我是強烈不建議我們團隊內(nèi)部大量的使用implicit。在我看來,多寫兩行代碼,顯式的轉(zhuǎn)換一下,真的不是什么大事!
上述內(nèi)容就是如何進行scala隱式轉(zhuǎn)換及Spark源碼解析,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。