scala的隐式转换基本使用

33 阅读3分钟

内容如下:

1. 什么是隐式转换

2. 隐式函数

3.隐式参数

4.转换规则

(一)什么是隐式转换

隐式转换是指:scala自动把一种类型转成另一种类型的过程。这个过程对用户编程而言不可见,不需要用户手动编写代码。

package imp
/*
* 隐式转函数: 把double 换成 int
* 隐式函数
*
* */
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。把高精度的转换成低精度的,错误!!!
    
    println(i)

  }
}

(二)隐式函数

在scala.Predef中,可以看到有系统提供了默认的情况。

隐式函数的定义:通过implicit关键字修饰的函数,它的功能是把一种类型的数据转成另一种类型。

implicit def 函数名(参数:类型1):类型2 = {

函数体

}

注意点:

(1)调用时机,在系统自动把数据从类型1隐式转为类型2时出错时,被自动调用。

(2)函数名可以自定义(一般取名为类型1to类型2),但是参数和返回值必须有限制。

【例子】:

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 // 把double --> int。把高精度的转换成低精度的,错误!!!
    i = 2.2
    i = 3.3

    println(i)
  }
}

【运行结果】: image.png

(三)隐式参数

隐式参数:如果在写函数的参数的时候,预计某个参数的默认值可能会被修改。可以设置隐式参数

package imp

/*
*
* 隐式参数:如果在写函数的参数的时候,预计某个参数的默认值可能会被修改。可以设置隐式参数
*
*     implicit password:String = "123456"
* */
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")
  }
}

【运行结果】: image.png

(四)转换规则

具体来说有两点:无歧义规则,不能多次转换。

package imp

/*
* 隐式转换函数的规则:
    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)}

  implicit def k2km(m:M):KM = { new KM(m.value / 1000)}
  // 补充隐式函数。把BM -> M
  implicit def bm2m(bm:BM):M = { new M(bm.value * 100)}
  // implicit def k2km(m:M):KM = { new KM(m.value / 1000)}

  // 补充隐式函数。把BM -> M
    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)
    }
  }

【运行结果】: image.png