Scala语法基础之隐式转换
一,简介
从类型S到类型T的隐式转换由具有函数类型S => T的隐式值定义,或者通过可转换为该类型的值的隐式方法来定义。隐含转换适用于两种情况:
1),如果表达式e是类型S,并且S不符合表达式的期望类型T.
2),在具有类型S的e的e.m表达中,如果m不表示S的成员
在第一种情况下,搜索适用于e并且其结果类型符合T的转换c。在第二种情况下,搜索适用于e的转换c,其结果包含名为m的成员。
列表[Int]的两个列表xs和ys的以下操作是合法的:
xs <= ys
前提是下面定义的隐式方法list2ordered和int2ordered在范围内:
implicit def list2ordered[A](x: List[A])
(implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] =
new Ordered[List[A]] { /* .. */ }
implicit def int2ordered(x: Int): Ordered[Int] =
new Ordered[Int] { /* .. */ }
隐式导入的对象scala.Predef声明了一些预定义的类型(例如Pair)和方法(例如,assert),还有一些隐式转换。例如,当调用期望java.lang.Integer的Java方法时,可以自由地传递一个scala.Int。这是因为Predef包含以下隐式转换:
import scala.language.implicitConversions
implicit def int2Integer(x: Int) =
java.lang.Integer.valueOf(x)
因为隐式转换可能有缺陷,如果不加区别地使用,编译器在编译隐式转换定义时会发出警告。
若要关闭警告,请采取以下任何一种操作:
1),将scala.language.implicitConversions导入隐式转换定义的范围
2),调用编译器时,加上:-language:implicitConversions
当编译器应用转换时,不会发出警告。
二,demo
1,第一种情况的demo
直接使用,会报错
val i: Int = 1.5
定义隐式转化方法
implicit def double2Int(d: Double) = d.toInt
再次执行就正常了
2,第二种情况的demo
class MYDF{
def show(sw : String) = println(sw)
}
object RDD2DF{
implicit def rdd2df(s : MYRDD) = new MYDF
}
class MYRDD
object AminalType extends App{
import yourpackage.RDD2DF._
val test = new MYRDD
test.show("RDD converts into DF")
}
编译器在执行test 对象的时候并没有show方法,此时编译器就会在作用域范围内查找能使其编译通过的隐式视图,找到RDD2DF的隐式转换方法后,会先进行隐式转换,之后调用show方法。
3,隐式转化参数
在定义一个方法时可以把最后一个参数列表定义为隐式参数。这个在spark内部使用也是非常广泛,比如前面发表的文章<spark源码系列之累加器实现机制及自定义累加器>就用到了。
如果方法有多个隐式参数,只需一个implicit修饰即可。当调用包含隐式参数的方法是,如果当前上下文中有合适的隐式值,则编译器会自动为改组参数填充合适的值。如果没有编译器会抛出异常。当然,标记为隐式参数的我们也可以手动为该参数添加默认值。def foo(n: Int)(implicit t1: String, t2: Double = 3.14)。
少了第一步会报错。
此种情况在Spark中的使用,举例:
def accumulator[T](initialValue: T, name: String)(implicit param: AccumulatorParam[T])
: Accumulator[T] = {
val acc = new Accumulator(initialValue, param, Some(name))
cleaner.foreach(_.registerAccumulatorForCleanup(acc))
acc
}
三,总结
彻底搞懂scala隐式转换,对我们了解spark及spark相关产品源码,如mongodb,redis等于spark结合实现源码原理有着至关重要的作用。除了前面讲的<spark源码系列之累加器实现机制及自定义累加器>用到了demo3,后面讲mongodb结合spark的源码及spark的源码都用到demo2和demo1这两种情况了。欢迎大家等待浪尖持续更新。
- Java标准I/O流编程一览笔录
- 十分钟学perl够用(客服MM都懂了)
- Java多线程并发编程一览笔录
- Tomcat6/7应用服务器-禁用RC4等弱密码套件
- mybaits3整合spring总结
- 如何使用Airgeddon找回WiFi密码
- 设计缺陷将导致亚马逊Echo变身成为监听设备
- Unity引擎与C#脚本简介
- Redis分布式缓存系统Lua脚本食用指引
- 基于复杂方案OWSAP CsrfGuard的CSRF安全解决方案(适配nginx + DWR)
- XMLHttpRequest对象如何兼容各浏览器使用?
- Java使用wsdl生成axis版本webservice服务端/客户端代码
- Java微信支付快速入门&工具类
- redis集群 - linux安装与配置笔记
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- codeforces 1283D(BFS)
- codeforces 1213D2(贪心+思维)
- codeforces 1426E(贪心)
- codeforces 1374E1(贪心+优先队列)
- codeforces 455A(dp)
- codeforces 1296E1(贪心+思维)
- codeforces 1216E1(数学+暴力)
- JDBC基础入门使用
- codeforces 1353E(dp)
- codeforces 1396A(构造)
- codeforces 1335E1+E2(思维)
- JSP开发基础入门学习1
- codeforces 1407C(数学+交互题)
- codeforces 1420C1
- codeforces 1417D(思维,构造)