Spark基础-scala学习(八、隐式转换与隐式参数)
大纲
- 隐式转换
- 使用隐式转换加强现有类型
- 导入隐式转换函数
- 隐式转换的发生时机
- 隐式参数
隐式转换
- 要实现隐式转换,只要程序可见的范围内定义隐式转换函数即可。Scala会自动使用隐式转换函数。隐式转换函数与普通函数唯一的语法区别就是,要以implicit开头,而且一定要定义函数返回类型
- 案例:特殊售票窗口(只接受特殊人群,比如学生、老人等)
scala> :paste
// Entering paste mode (ctrl-D to finish)
class SpecialPerson(val name:String)
class Student(val name:String)
class Older(val name:String)
implicit def object2SpecialPerson(obj:Object):SpecialPerson = {
if(obj.getClass == classOf[Student]){val stu = obj.asInstanceOf[Student];new SpecialPerson(stu.name)}
else if(obj.getClass == classOf[Older]){val older = obj.asInstanceOf[Older];new SpecialPerson(older.name)}
else Nil
}
var ticketNumber = 0
def buySpecialTicket(p:SpecialPerson) = {
ticketNumber+=1
"T-"+ticketNumber
}
// Exiting paste mode, now interpreting.
<pastie>:15: warning: implicit conversion method object2SpecialPerson should be enabled
by making the implicit value scala.language.implicitConversions visible.
This can be achieved by adding the import clause 'import scala.language.implicitConversions'
or by setting the compiler option -language:implicitConversions.
See the Scaladoc for value scala.language.implicitConversions for a discussion
why the feature should be explicitly enabled.
implicit def object2SpecialPerson(obj:Object):SpecialPerson = {
^
defined class SpecialPerson
defined class Student
defined class Older
object2SpecialPerson: (obj: Object)SpecialPerson
ticketNumber: Int = 0
buySpecialTicket: (p: SpecialPerson)String
scala> val s = new Student("leo")
s: Student = Student@4d266391
scala> buySpecialTicket(s)
res0: String = T-1
scala> val o = new Older("Jike")
o: Older = Older@6afbe6a1
scala> buySpecialTicket(o)
res1: String = T-2
使用隐式转换加强现有类型
- 隐式转换可以在不知不觉中加强现有类型的功能。也就是说,可以为某个类定义一个加强版的类,并定义互相之间的隐式转换,从而让源类在使用加强版的方法时,由scala自动进行隐式转换为加强类,然后再调用该方法
- 案例:超人变身
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Man(val name:String)
class Superman(val name:String){
def emitLaser = println("emit a laster!")
}
implicit def man2superman(man:Man):Superman = new Superman(man.name)
// Exiting paste mode, now interpreting.
defined class Man
defined class Superman
man2superman: (man: Man)Superman
scala> val leo = new Man("leo")
leo: Man = Man@618e7761
scala> leo.emitLaser
emit a laster!
隐式转换函数的作用域与导入
- scala会使用两种隐式转换,一种是源类型,或者目标类型的伴生对象内的隐式转换函数;一种是当前程序作用域内的可以用唯一标识符表示的隐式转换函数
- 如果隐式转换函数不在上述两种情况下的话,那么就必须手动使用import语法引入某个包下的隐式转换函数,比如import test._ 通常建议,仅仅在需要进行隐式转换的地方,比如某个函数或者方法内,用import导入隐式转换函数,这样可以缩小隐式转换函数的作用域,避免不需要的隐式转换。
隐式转换的发生时机
- 调用某个函数,但是给函数传入的参数的类型,与函数定义的接收参数类型不匹配(案例:特殊售票窗口)
- 使用某个类型的对象,调用某个方法,而这个方法并不在于该类型时(案例:超人变身)
- 使用某个类型的对象,调用某个方法,虽然该类型有这个方法,但是给方法传入的参数类型,与方法定义的接收参数的类型不匹配(案例:特殊售票窗口加强版)
- 案例:特殊售票窗口加强版
scala> :paste
// Entering paste mode (ctrl-D to finish)
class TicketHouse {
var ticketNumber= 0
def buySpecialTicket(p:SpecialPerson) = {
ticketNumber += 1
"T-"+ticketNumber
}
}
// Exiting paste mode, now interpreting.
defined class TicketHouse
scala> val leo = new Student("leo")
leo: Student = Student@217dc48e
scala> val ticket = new TicketHouse
ticket: TicketHouse = TicketHouse@7a5a26b7
scala> ticket.buySpecialTicket(leo)
res1: String = T-1
隐式参数
- 所谓的隐式参数,指的是在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数
- Scala会在两个范围内查找:一种是当前作用域内可见的val或var定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值
- 案例:考试签到
scala> :paste
// Entering paste mode (ctrl-D to finish)
class SignPen{
def write(content:String) = println(content)
}
implicit val signPen = new SignPen
def signForExam(name:String)(implicit signPen:SignPen){
signPen.write(name+" come to exam in time.")
}
// Exiting paste mode, now interpreting.
defined class SignPen
signPen: SignPen = SignPen@6c4d0224
signForExam: (name: String)(implicit signPen: SignPen)Unit
scala> signForExam("leo")(signPen)
leo come to exam in time.
Spark基础-scala学习(八、隐式转换与隐式参数)的更多相关文章
- Spark基础-scala学习(七、类型参数)
类型参数是什么 类似于java泛型,泛型类 泛型函数 上边界Bounds 下边界 View Bounds Context Bounds Manifest Context Bounds 协变和逆变 Ex ...
- Spark基础-scala学习(四、函数式编程)
函数式编程 将函数赋值给变量 匿名函数 高阶函数 高级函数的类型推断 scala的常用高阶函数 闭包 sam转换 currying函数 return 将函数赋值给变量 scala中的函数是一等公民,可 ...
- Spark基础-scala学习(二、面向对象)
面向对象编程之类 //定义一个简单的类 scala> :paste // Entering paste mode (ctrl-D to finish) //类默认public的 class He ...
- Spark基础-scala学习(三、Trait)
面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...
- Spark基础-scala学习(一、入门)
Scala解析器的使用 REPL:Read(取值)-> Evaluation(求值)-> Print(打印)->Loop(循环).scala解析器也被称为REPL,会快速编译scal ...
- Spark基础-scala学习(五、集合)
集合 scala的集合体系结构 List LinkedList Set 集合的函数式编程 函数式编程综合案例:统计多个文本内的单词总数 scala的集合体系结构 scala中的集合体系主要包括:Ite ...
- Scala学习之路 (八)Scala的隐式转换和隐式参数
一.概念 Scala 2.10引入了一种叫做隐式类的新特性.隐式类指的是用implicit关键字修饰的类.在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换. 隐式转换和隐式参数是Scal ...
- Scala基础:闭包、柯里化、隐式转换和隐式参数
闭包,和js中的闭包一样,返回值依赖于声明在函数外部的一个或多个变量,那么这个函数就是闭包函数. val i: Int = 20 //函数func的方法体中使用了在func外部定义的变量 那func就 ...
- 大数据技术之_16_Scala学习_06_面向对象编程-高级+隐式转换和隐式值
第八章 面向对象编程-高级8.1 静态属性和静态方法8.1.1 静态属性-提出问题8.1.2 基本介绍8.1.3 伴生对象的快速入门8.1.4 伴生对象的小结8.1.5 最佳实践-使用伴生对象解决小孩 ...
随机推荐
- openstack系列文章(1)devstack安装测试Queens
1.在OpenStack 圈子中,有这么一句名言:”不要让朋友在生产环境中运行DevStack.但是初学者在没有掌握OpenStack CLI的情况下用devstack安装测试环境还是不错的.本系列文 ...
- Rsync未授权访问漏洞的修复
转自:https://www.cnblogs.com/KevinGeorge/p/9648028.html 配置文件/etc/rsync.conf解析: motd file -> motd文件位 ...
- Hbase的基本操作(CDH组件可用)
Habse创建一张表: 1,创建一个命名空间NameSpace(命名空间NameSpace指的是一个表的逻辑分组 ,同一分组中的各个表有类似的用途,相当于关系型数据库中的DataBase) ...
- vue+elementUI表格列显示隐藏遇到bug
在最近的项目中,有需求要做到根据字段显示列,原来以为简单的v-if可以解决. 在开发的过程中遇到问题, <el-table ref="multipleTable" :data ...
- 解决拼音输入法会触发input事件的问题
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script sr ...
- windows10系统安装Oralce11g时遇到INS-13001环境不满足最低要求
升级win10系统之后,需要重新安装Oracle,因为在安装Oralce11g时,使用64位的会出现各种不兼容问题,我每次安装都是使用32位的数据库. 在安装时点击setup.exe之后,出现了:[I ...
- Python——教你画朵太阳花
用python中的turtle函数画个太阳花,有以下几个步骤 1.首先,我们在开始中找到Python语言的IDLE软件脚本 2.然后出现该软件界面,如图,点击上面的Eile 3.然后在 ...
- sql语句创建数据表
unsigned 数值类型 无符号化 AUTO_INCREMENT 自增长 PRIMARY KEY 唯一主键 COMMENT 备注信息 BIT 类型只有1和0两个值 enum 枚举数值类型 UNIQU ...
- JAVA 8 日期工具类
JAVA 8 日期工具类 主题描述 JAVA中日期时间的历史 代码成果 主题描述 JAVA的日期时间一直比较混乱,本来以为joda会是巅峰,但是JAVA 8改变了我的思想.但是即便在JAVA 8面前, ...
- Redis sentinel之集群搭建
环境 由于不太熟悉docker,所以,把docker当虚拟机来用,服务器环境如下: Redis Server 环境搭建 Redis Server 01 搭建 并且制作Redis镜像 容器建立 # do ...