隐式函数

129 阅读2分钟

一:隐式函数

  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.5 / //把double ---> int。把高精度的转换成低精度的时,错误!!!!
    i= 1.2 // 把double  ----> int  把高精度的转换成低精度的,错误!!
    i = 2.2
    i = 3.3
    println(i)
  }
}

二:隐式参数:

如果在后面函数的参数的时候,预计某个参数的默认值可能会被修改。可以设置隐式参数。 implicit password:String="123456"

object imp02 {
  implicit val defaultPassword:String = "888888"

  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,B->C,但是不能直接从A->C。来通过具体的代码来说明。

object imp03 {
  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) }
  // 补充隐式函数:把 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)
    println(m1)
    println(m2)
  }
}