implicit
关键词,在Scala的开发中是做隐式转换时用到的,而隐式转换在Scala开发中的作用是,当操作的实体无法满足操作条件时,如果拥有隐式转换的条件,那么会自动触发,使得操作的实体拥有符合操作条件的特性,可以看成是对实体的一种增强。
隐式转换的应用场景分为两种:
- 隐式转换函数:主要用作类的增强
- 隐式转换值:方法传参的默认值或者某类型的默认值
注意:使用隐式转换有一个很重要的点,一种类型的隐式转换,在一个运行流程中只能存在一个,也就是参数类型、返回值一样的隐式转换不能共存
首先给大家介绍的是隐式转换函数。
package com.wy
class SpecialPeron(var name: String)
class Older(var name: String)
class Student(var name: String)
class Teach(var name: String)
object ImplicitDemo {
def buySpecialTickWindow(peron: SpecialPeron): Unit = {
if (peron != null) {
println(peron.name + "购买了一张特殊票!")
} else {
println("你不是特殊人群,不能在此买票!")
}
}
//隐式转换函数:作用是本来buySpecialTickWindow方法接收的是SpecialPeron类
//但是有了这个方法,就可以传入其他的类型,转换的方式在转换函数中写明就可以了
implicit def anytoSpecialPerson(any: Any): SpecialPeron = {
/**
* 这里用模式匹配,你也可以用if/else只是比较麻烦
*/
any match {
case any: Older => new SpecialPeron(any.asInstanceOf[Older].name)
case any: Student => new SpecialPeron(any.asInstanceOf[Student].name)
case _ => null
}
}
def main(args: Array[String]): Unit = {
val older = new Older("老人")
val student = new Student("学生")
val teacher = new Teach("讲师")
buySpecialTickWindow(older)
buySpecialTickWindow(student)
buySpecialTickWindow(teacher)
}
}
上面就是隐式转换函数,用来增强程序的可执行性,来弥补程序运行时,被操作的实体类功能有缺陷,注意它的触发需要你的操作实体和操作的业务场景符合隐式转换的形参数类型以及返回值
这个时候有人有小伙伴,可能会迷惑,当隐式转换需求量很大的时候同类型用到的不止有一个怎么办,因为前面也说了,一个运行流程里一个类型的隐式转换方法只能有一个,如果有两个运行的时候是会报错的,这个问题看我下面给大家准备的这个例子
package com.wy
import java.io.File
import scala.io.Source
/*
这个注释的object 是想让大家看一下一般情况下我们如何用普通手段读取文件数据的,让大家看下面的东西的时候不迷糊
object ImplicitsTest {
def main(args: Array[String]): Unit = {
val file = new File("C:\\Users\\小象\\Desktop\\6月\\0618\\1.txt")
println(Source.fromFile(file).mkString)
//println(file.read)
}
}*/
//-------------------------------下面正题开始了,敲黑板了,注意----------------------------------------------
//这里自定义的RichFile相当于File的增强类 用主构造器来包含被他增强的类
class RichFile(val file: File) {
def read = {
Source.fromFile(file).mkString
}
}
//前面说了implicit是隐式转换的关键字 这里定义一个隐式转换函数把当前类型转换成增强后的类型
//这也是我前面说的一个运行流程中一个类型只有一个隐式转换的实行方法,在正式开发的时候这些隐式转换都是写在一个object里面的用的时候import调用就行
object Context {
//File类 --> RichFile自定义类
implicit def file2RichFile(file: File) = new RichFile(file)
}
//使用的时候如下
object Hello_Implicit_Conversions {
def main(args: Array[String]): Unit = {
//导入隐式转换
import Context.file2RichFile
//当然你也可以把隐式转换任然写在这里
//implicit def file2RichFile(file: File) = new RichFile(file)
//File类本身没有read方法 通过隐式转换完成
//这里的read方法是RichFile类中的方法 需要通过隐式转换File --> RichFile
println(new File("C:\\1.txt").read)
}
}
隐式转换值比较简单它主要是两种使用场景,第一种是给方法的参数设定默认值,不过方法要进行柯里化
package com.wy
object ImplicitValue {
def main(args: Array[String]): Unit = {
println(myCurry3(1))
//正常调用
println(myCurry3(1)(3))
//当y没有传入参数的时候,默认为2
def myCurry3(x:Int)(implicit y:Int=2)=x+y
}
}
第二种用途是给一个类型赋予默认值,达到当使用这个类型时不需要去赋值或实例化,就可以直接使用
package com.wy.driver
object TTT {
def main(args: Array[String]): Unit = {
implicit val i:Int=6
println(i)
}
}