隐式转换
当编译器第一次编译失败时,会在当前环境中查找能让代码编译通过的方法,用于将类型转换,实现俄二次编译
隐式转换解析机制:
- 首先会在当前代码作用域下查找隐式实体(隐式方法,隐式类,隐式对象)
- 如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。类型的作用域是指与该类型相关联的全部伴生对象以及该对象所在包的包对象
1、隐式函数
隐式函数可以在不需要改变任何代码的情况下,拓展某个类的功能
def implicit_func(): Unit = {
//普通方式调用
// val myRichInt = new MyRichInt(2023)
// println(myRichInt.myMax(1999))
//隐式函数调用
implicit def convert(num: Int): MyRichInt = new MyRichInt(num)
println(2021.myMax(2023))
}
//自定义类
class MyRichInt(val self: Int) {
//自定义方法
def myMax(n: Int): Int = if (n > self) n else self
def myMin(n: Int): Int = if (n < self) n else self
}
2、隐式类
- Scala 2.10后提供了隐式类,可以使用
implicit
声明类,隐式类非常强大。同样可以拓展类的功能,在集合中隐式类会发挥重要的作用 - 隐式类的构造器有且仅有一个
- 隐式类必须被定义在”类“或”伴生对象“或”包对象“里,即隐式类不能是顶级的
def implicit_class(): Unit = {
implicit class MyRichInt(val self: Int) {
//自定义方法
def myMax2(n: Int): Int = if (n > self) n else self
def myMin2(n: Int): Int = if (n < self) n else self
}
println(2023.myMin2(201))
}
3、隐式参数
- 普通方法或者函数中的参数可以通过
implicit
关键字声明为隐式参数,调用该方法时,就可以传入该参数,编译器会在相应的作用域寻找符合条件的隐式值 - 同一个作用域中, 相同类型的隐式值只能有一个
- 编译器按照隐式参数的类型去寻找对应类型的隐式值,与隐式值无关
- 隐式参数优于默认参数
def implicit_param(): Unit = {
//普通函数传参调用
def sayHello(name: String): Unit = {
println(s"hello $name")
}
sayHello("scala")
//隐式参数传入调用
implicit val name: String = "merlin"
def sayHi(implicit name: String = "scala") {
println(s"hi $name")
}
sayHi
//进阶隐式参数使用
// 无需定义参数,直接时候implicitly[DataType] 表示获取对应数据类型的隐式参数
implicit val age: Int = 23
def myAge(): Unit = {
println(s"my age is ${implicitly[Int]}")
}
myAge()
}