一、导入
在Scala编程中,类型转换是一个常见的需求。我们都知道,将精度低的类型转换为精度高的类型(如Int转Double)是自动进行的隐式转换,但反过来呢?这节课我们将深入探讨Scala强大的隐式转换机制,学习如何让编译器在类型不匹配时自动进行类型转换,从而提高代码的灵活性和可维护性。
二、讲授新课
(一)什么是隐式转换
隐式转换是Scala自动将一种类型转换为另一种类型的过程。这个过程对开发者透明,无需手动编写转换代码。
案例:隐式转换函数的使用
package imp
/*
隐式转换函数:把 double 转成 int
隐式函数
1.implicit 修饰
2.它会自动被调用当系统检测到隐式转换失败的时候去自动调用
3.函数的名字不重要重要的是它的输入数据的类型和返回值类型
它的作用是:偷偷地把一种类型的数据转成另一种类型的数据
*/
object imp01 {
implicit def double2int(d:Double):Int = {
println("调用 double2int")
d.toInt
}
def main(args: Array[String]): Unit = {
var i:Int = 1;
val d:Double = i // 把Int-->double 隐式函数 把精度低的数据转成精度高的数据,这是可以的
i = 1.2
i = 2.2
i = 3.2// 把double--> int 把高精度的转成低精度的 错误
println(i)
}
}
(二)隐式参数
隐式参数用于处理那些可能会频繁修改的默认参数值。通过使用隐式参数,可以在不修改函数调用代码的情况下改变参数的默认值。
案例:隐式参数的使用
package imp
/*
隐式参数:如果在写函数的参数的时候,预计某个参数的默认值可能会被修改可以设置隐式参数
*/
object imp02 {
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")
}
}
(三)转换规则
隐式转换虽然强大,但必须遵循特定的转换规则:
规则1:无歧义规则
不能在同一作用域定义两个相同的转换函数(函数名不同但输入输出类型相同)
规则2:不能多次转换
隐式转换一次只能进行一次转换,不能自动进行链式转换(如A->B->C)
案例:隐式转换规则演示
package imp
/*
隐式转换函数的规则
1.无歧义规则
不能写两个相同的转换函数
2.不能自动多次转换
A -> B B -> C 不等价于 A -> C
*/
object imp03 {
class KM(val value: Double) {
override def toString: String = s"${value} 千米"
}
class M(val value: Double) {
override def toString: String = s"${value} 米"
}
class BM(val value: Double) {
override def toString: String = s"${value} 百米"
}
// 隐式转换:千米 -> 米
implicit def km2m(km: KM): M = new M(km.value * 1000)
// 隐式转换:百米 -> 米
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)
println(m1)
println(m2)
}
}