如何进行scala隐式转换及Spark源码解析
本篇文章为大家展示了如何进行scala隐式转换及Spark源码解析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
十载专注成都网站制作,成都定制网站,个人网站制作服务,为大家分享网站制作知识、方案,网站设计流程、步骤,成功服务上千家企业。为您提供网站建设,网站制作,网页设计及定制高端网站建设服务,专注于成都定制网站,高端网页制作,对成都格栅板等多个领域,拥有丰富的营销推广经验。
隐式转换,是scala当中一个重要的特性,今天我们结合自己的例子和spark源码,争取对隐式转换有一个更加深入的了解。
关于implicit有3种使用方式,implicit def、implicit class以及implicit 参数
首先看一下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()
}
}
在上面的代码当中,我们定义了3个class,Man、Woman、Child,他们之间没有任何继承关系。下面的main函数当中,我们声明了Man、Woman、Child,各一个实例,我们考虑,作为男人来讲,是不是也不一定只能是工作,适当的休闲和娱乐是不是也是可以的。所以我们做了2个隐式转换的函数,manToWoman和manToChild,需要注意的是,这两个函数名其实一点都不重要,我们只是希望看起来更容易理解一些,你写个aaa或者bbb,一点问题都没有。
编译过程大概是这样的:
1、编译man.shop(),发现并没有shop方法,即将报错
2、报错之前,搜索一下作用域内,有没有隐式转换函数,能够支持man对shop的调用,找到了manToWoman。
3、把man变成woman,调用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()
}
}
这个当中实现的效果看起来和前一种差不多,其实它的语义是完全不同的。编译过程大概是这样的:
1、编译man.shop(),发现并没有shop方法,即将报错
2、报错之前,搜索一下作用域内,看看有没有隐式转换类,能够为man提供shop方法,找到了ManConvert
3、将man转换为ManConvert,执行shop方法。
最后我们再看一下implicit参数的用法:
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
}
}
我们为Man增加了一个marry的方法,它的参数w是implicit的,然后调用的时候,我们先在前面声明了一个implicit 类型的woman,之后调用marry但是不指定参数,这样是不会报错得到。但是如果我们在marry的前面声明了2个implicit的woman,那么marry还是会报错的。
换成人类的语言来解释这件事:一个男人要结婚,如果指定结婚对象,那没问题,如果没指定,那就看看身边有没有适合的结婚对象,有的话,就直接生米煮成熟饭,可是如果身边有2个,好吧,我也不知道该娶哪个!
结合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的源码当中我们找到了下面这段:
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的学习和理解,非常重要。
但是,我要说但是,凡事都有其两面性,implicit在带来代码的紧凑和精炼的同时,负作用就是可读性极差;特别是在工作的初级阶段,我是强烈不建议我们团队内部大量的使用implicit。在我看来,多写两行代码,显式的转换一下,真的不是什么大事!
上述内容就是如何进行scala隐式转换及Spark源码解析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。
文章题目:如何进行scala隐式转换及Spark源码解析
文章出自:http://pwwzsj.com/article/pjcsjc.html