聊聊Scala编程中隐式相关的那些事儿(一)

大数据顶级框架Spark是用Scala编的,学习大数据掌握Scala编程很有必要。为什么想聊Scala编程中的隐式转换、隐式函数、隐式值、隐式类这个话题呢,因为隐式真的很“优雅”。老子在道德经里说,“是以圣人居无为之事,行不言之教,万物作而弗始也,为而弗志也,成功而弗居也。夫唯弗居,是以弗去。”核心思想就是无为,托举万物而不居功。悄悄地把事情做好了却不与人谈及自己的功劳,而Scala中的一系列的隐式操作就是如此,把事情做了却把自己隐藏起来。

我们先看看隐式转换,从一个最简单的场景讲起。Scala语言对数据的类型有着很强的约束,针对某种数据类型的操作往往不适用于另外一种数据类型,所以需要对数据类型进行转换。看下面这个简单的代码示例:

71c349470f01466a9a37318b540a7183.png

 针对Int类型的a和Double类型的b,我们想计算它们数据本身的长度,所以调用了.length,但是Idea编辑器马上让length变红了,表明这种类型的数据没有length方法可以用。那怎么办呢,可以这样a.toString.length或者b.toString.length。这样编程功能上是没什么问题的,可是显得非常笨拙和臃肿,如果某个程序需要大量的这样的操作,每次都要把toString这个方法显式地调用一下,那也太不方便了。于是,Scala语言的设计者Martin Odersk引入了隐式转换,在上图的第5行加上这样一个隐式转换函数:

implicit def num2String(x:AnyVal) = x.toString

这样每次当程序中需要将数值类型的数据转化为String类型时,就不用显式地调用toString方法,编译器会自动识别什么时候需要转换然后悄悄地帮你完成转换,这样你的代码就显得很优雅。插句题外话,Martin Odersky发明了Scala语言,Java编译器也是他写的,后面我打算写一篇介绍他的文章。

隐式转换是由implicit关键字定义的隐式转换函数来实现的,需要注意的是隐式函数只有在它的作用域中才能发挥作用。隐式函数的名称是可以任意定义的,因为它是隐式,它做事从不留名,所以名字对它来说只是一种称谓,并不重要,重要的是函数参数的类型和返回值的类型,所以它的完整表达是:

implicit def num2String(x:AnyVal): String = x.toString

隐式函数的输入只有1个参数,它的作用决定了它没有必要有多个参数。可以定义多个隐式函数,但是在需要用到时必须保证有且只有1个隐式函数被识别,否则编译器会不知道你到底要做什么。所以,上面的隐式函数也可以拆开写成这样:

implicit def int2String(x:Int): String = x.toString
implicit def double2String(x:Double): String = x.toString

但是,如果你再来1个,那程序就会报错:

implicit def int2String02(x:Int): String = x.toString

另外,还要注意的是,在隐式转换函数内部不能调用自己,也就是说不允许递归或者说嵌套使用。当然,正常人也不会这么干。

数据类型的转换在大数据编程中经常使用,当我们传给函数或方法的数据或变量不是目标参数类型时,就需要把当前的数据类型转换成函数或方法能支持的类型,这个时候就可以用隐式转换啦。

好了,今天先说到这里,后续继续聊聊隐式值、隐式类。。。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值