第10章 隐式转换
当编译器第一次编译器失败的时候,会再次编译,用于将类型进行转换,实现二次编译。
二次编译的时候,实现隐式转换
10.1 隐式函数
object Test02{
def main(args:Array[String]):Unit={
val new12 = new MyRichInt(12)
println(new12.myMax(15))
// 比较12 和 15的大小,返回较大的数
// println(12.myMax(15))
// 但是Int类型中没有myMax方法
// 试图将Int类型 隐式转换为 MyRichInt,然后调用里面的myMax方法
// 定义隐式函数
implicit def convert(num:Int):MyRichInt = new MyRichInt(num)
println(12.myMax(15)) // 定义了隐式转换,如果Int通不过,就会把Int类型隐式转换为MyRichInt
}
}
// 自定义类
// 试图将Int类型隐式转换为MyRichInt类
class MyRichInt(val self:Int){
// 自定义比较大小的方法
def myMax(n:Int):Int = if( n < self ) self else n
def myMin(n:Int):Int = if( n < self ) n else self
}
10.2 隐式参数
通过implicit关键字,声明为隐式参数,调用该方法时,就可以传入该参数,编译器会在相应的作用域寻找符合条件的隐式值
1)说明
(1)同一个作用域中,相同类型的隐式值只能有一个
(2)按照类型去找隐式值, 与名称无关。
同一作用域内,相同隐式参数的类型只能有一个
(3)隐式参数优先于默认参数
object Test02{
def main(args:Array[String]):Unit={
def sayHello(name:String):Unit={
println("hello"+name)
}
sayHello("张三")
implicit val str:String = "我是隐式参数"
// say(正常的参数)(隐式参数)
def sayHi()(implicit name:String):Unit={
println("hello"+name)
}
sayHi
sayHi()
// 不需要任何参数,只需要从隐式参数中去寻找即可
// sayHi(隐式参数)
def sayHi2(implicit name:String):Unit={
println("hello"+name)
}
sayHi2
//sayHi2() //!!!报错
// 简便写法
implicit val age:Int = 18
def hiAge():Unit={
println("hi," + implicitly[Int]) //调用Int类型的隐式值
}
hiAge
}
}
10.3 隐式类
用implict声明类
当前隐式类的所有方法和属性都可以使用
object Test02{
def main(args:Array[String]):Unit={
println(12.myMax(15))
}
// 定义隐式类 ,如果Int类型找不到,就会隐式转换为MyRichInt类
implicit class MyRichInt(val self:Int){
def myMax(n:Int):Int = if( n < self ) self else n
def myMin(n:Int):Int = if( n < self ) n else self
}
}
10.4 隐式解析机制
如果编译通不过后,
(1)会在代码的作用域下寻找隐式实体(隐式方法、隐式类、隐式对象)
(2)隐式参数的类型的作用域里查找