隐式函数定义:
通过implicit关键字修饰的函数,它的功能是把一种类型的数据转成另一种类型
implicit def 函数名(参数:类型1):类型2 = {
函数体
}
!!注意:
- 调用时机,在系统自动把数据从类型1隐式转为类型2时出错时,被自动调用
- 函数名可以自定义(一般取名为
类型1 to 类型2),但是参数和返回值必须有限制
示例代码:
/*
隐式转换函数:把double转成int
隐式函数
1.implicit 修饰
2.它会自动被调用。当系统检测到隐式转换失败的时候,去自动调用
3.函数的名字不重要,重要的是它的输入数据的类型和返回值类型
作用:偷偷地把一种类型的数据转换成另一种类型的数据!
*/
object day01 {
implicit def double2int(d:Double):Int={
println("调用 double2int")
d.toInt
}
def main(args: Array[String]): Unit = {
var i:Int=1
val d:Double=i
i=1.2
i=2.2
i=3.3
println(i)
}
}
隐式参数
示例代码1:
/*
隐式参数:如果在写函数的参数的时候,预计某个参数的默认值可能会被修改。可以设置隐式参数
implicit password:String="123456"--->隐式参数
*/
object day02 {
implicit val defaultPassword:String="88888888"
def reg(name:String)(implicit password:String="123456"):Unit= {
println(s"用户名:${name},密码:${password}")
}
def main(args: Array[String]): Unit = {
reg("小文")
reg("小玉")("admin")
}
}
示例代码2:
/*
隐式参数:如果在写函数的参数的时候,预计某个参数的默认值可能会被修改。可以设置隐式参数
implicit password:String="123456"--->隐式参数
*/
object day02 {
class KM(var value:Double) {
override def toString:String=s"${value}千米"
}
class BM(var value:Double) {
override def toString:String=s"${value}百米"
}
class M(var value:Double) {
override def toString:String=s"${value}米"
}
//补充隐式转换函数,把KM->M
implicit def km2m(km:KM):M={new M(km.value*1000)}
implicit def k2km(m:M):KM={new KM(m.value/1000)}
//补充一个隐式函数,把BM->M
implicit def bm2m(bm:BM):M={new M(bm.value*100)}
def main(args: Array[String]): Unit = {
val km1=new KM(2)
val m1:M=km1
val m2:M=new BM(2)
val km2:KM=new M(2500)
println(m1)
println(m2)
println(km2)
}
}
转换规则
规则1:无歧义规则:不能重新定义两个相同的转换函数。如果有两个隐式转换函数,只有函数名不同,则会导致错误。
如下的代码会导致编译错误
implicit def fun1(a:Int):String = a.toString
implicit def fun2(b:Int):String = b.toString
错误的原因是这里有两个转换函数,导致代码在编译时,无法确定使用哪一个。
规则2:不能多次转换:在一次转换过程中可以把A->B,B->C,但是不能直接从A->C。来通过具体的代码来说明。
package pub
object Test {
class KM(var value: Double){override def toString: String = s"${value}千米"}
class BM(var value: Double){override def toString: String = s"${value}百米"}
class M(var value:Double){override def toString: String = s"${value}米"}
implicit def bm2km(bm:BM):KM = new KM(bm.value / 10)
implicit def m2bm(m:M):BM = new BM(m.value / 100)
def main(args: Array[String]): Unit = {
val mi = new M(1230)
val baimi1:BM = mi
println(baimi1)
val baimi = new BM(123)
val c:KM = baimi;
println(c)
val c1:KM = mi
}
}