Scala 隐式转换和隐式参数

介绍

Scala提供的隐式转换和隐式参数功能,是很是有特点的功能。是Java等编程语言所没有的功能。它能够容许你手动指定,将某种类型的对象转换成其余类型的对象。经过这些功能,能够实现很是强大,并且特殊的功能。编程

 

Scala的隐式转换,其实最核心的就是定义隐式转换函数,即implicit conversion function。定义的隐式转换函数,只要在编写的程序内引入,就会被Scala自动使用。Scala会根据隐式转换函数的签名,在程序中使用到隐式转换函数接收的参数类型定义的对象时,会自动将其传入隐式转换函数,转换为另一种类型的对象并返回。这就是隐式转换编程语言

 

隐式转换函数叫什么名字是无所谓的,由于一般不会由用户手动调用,而是由Scala进行调用。可是若是要使用隐式转换,则须要对隐式转换函数进行导入。所以一般建议将隐式转换函数的名称命名为“one2one”的形式。函数

 

Spark源码中有大量的隐式转换和隐式参数,所以必须精通这种语法。spa

 

 

知识点

1、隐式转换(案例:特殊售票窗口)对象

2、使用隐式转换增强现有类型(案例:超人变身)ci

3、隐式转换函数的做用域与导入作用域

4、隐式转换的发生时机(案例:特殊售票窗口增强版)get

5、隐式参数(案例:考试签到)源码

 

 

隐式转换

 

// 要实现隐式转换,只要程序可见的范围内定义隐式转换函数便可。Scala会自动使用隐式转换函数。隐式转换函数与普通函数惟一的语法区别就是,要以implicit开头,并且最好要定义函数返回类型。it

 

// 案例:特殊售票窗口(只接受特殊人群,好比学生、老人等)

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

}

 

使用隐式转换增强现有类型

 

 

// 隐式转换很是强大的一个功能,就是能够在不知不觉中增强现有类型的功能。也就是说,能够为某个类定义一个增强版的类,并定义互相之间的隐式转换,从而让源类在使用增强版的方法时,由Scala自动进行隐式转换为增强类,而后再调用该方法。

 

// 案例:超人变身

 

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)

 

val leo = new Man("leo")

leo.emitLaser

 

 

 

隐式转换的发生时机

 

// 1、调用某个函数,可是给函数传入的参数的类型,与函数定义的接收参数类型不匹配(案例:特殊售票窗口)

// 2、使用某个类型的对象,调用某个方法,而这个方法并不存在于该类型时(案例:超人变身)

// 3、使用某个类型的对象,调用某个方法,虽然该类型有这个方法,可是给方法传入的参数类型,与方法定义的接收参数的类型不匹配(案例:特殊售票窗口增强版)

 

// 案例:特殊售票窗口增强版

class TicketHouse {

  var ticketNumber = 0

  def buySpecialTicket(p: SpecialPerson) = {

    ticketNumber += 1

    "T-" + ticketNumber

  }

}

 

 

隐式参数

// 所谓的隐式参数,指的是在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的,用implicit修饰的对象,即隐式值,并注入参数。

// Scala会在两个范围内查找:一种是当前做用域内可见的valvar定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值

 

// 案例:考试签到

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.")

}

相关文章
相关标签/搜索