由于有精度损失,Double无法直接保存在Int中,而Int可直接保存在Double中,该如何解决这个问题呢
(一)什么是隐式转换
隐式转换是指:scala自动把一种类型转成另一种类型的过程。这个过程对用户编程而言不可见,不需要用户手动编写代码。
请大家一起回顾如下代码
var i:Int= 1;
val b:Double = i
在上面的代码的过程中,scala就帮我们做了一次隐式转换:把Int -> Double。
但是反过来,不能把Double → Int
var i:Int= 1.5; // 这里会报错
(二)隐式函数
在scala.Predef中,可以看到有系统提供了默认的情况。
隐式函数的定义:通过implicit关键字修饰的函数,它的功能是把一种类型的数据转成另一种类型。
implicit def 函数名(参数:类型1):类型2 = {
函数体
}
注意点:
(1)调用时机,在系统自动把数据从类型1隐式转为类型2时出错时,被自动调用。
(2)函数名可以自定义(一般取名为类型1to类型2),但是参数和返回值必须有限制。
package imp
object Demo01 {
def main(args: Array[String]): Unit = {
//隐式
//由于有精度损失,Double无法直接保存在Int中,而Int可直接保存在Double中
//
implicit def cent(D:Double):Int = {
println("方法被调用")
D.toInt
}
val I:Int = 1.1
println(I)
}
}
应用场景
上游数据类型的变化,导致下游消费数据的变化。此时,可以在不修改原来代码的情况下,去很方便地解决这个问题。
练习一:将Km转换为m
package imp
object Demo02 {
def main(args: Array[String]): Unit = {
class M(val value:Double) {
override def toString: String = value + "米"
}
class KM(val value:Double) {
override def toString: String = value + "米"
}
implicit def Km2m(KM: KM):M = {
println("KM => M 被调用")
new M(1000 * KM.value)
}
val Km1 = new KM(1)
val m1:M = Km1
println(m1)
}
}
结果:
练习二:将美元与人民币互相转换
package imp
object Demo03 {
def main(args: Array[String]): Unit = {
class my(val value:Double) {
override def toString: String = value + "美元"
}
class y(val value:Double) {
override def toString: String = value + "元"
}
implicit def my2y(my:my):y ={
println("美元转人民币已被调用")
new y(6.9 * my.value)
}
implicit def y2my(y:y):my = {
println("人民币转美元已被调用")
new my(0.14 * y.value)
}
val my1 = new my(2)
val y1 = new y(2)
var y2:y = my1
println("2美元等于" + y2 )
var my2:my = y1
println("2元等于" + my2 )
}
}
结果: