scala的隐式转换基本使用

22 阅读1分钟

导入

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

回顾代码

object imp01 {
  def main(args: Array[String]): Unit = {
   
    var i :Int = 1
    var d :Double = 1.1
    d = i //把 int 转换成 double 类型 相当于 d=i.toDouble
    println(s"d=${d}")  //d=1.0
    
//  i = d 把 double 转换成 int 报错!
  }
}

隐式函数

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

注意:

1.调用时机:在系统自动把数据从类型1隐式转为类型2时报错时,被自动调用

2.它的函数名不重要(一般的命名是 类型1 To 类型2),重要的是它的 参数和返回值 的类型

3.不能写两个同类型(参数和返回值的类型一致)的隐式转换函数,会报错

object imp01 {
// 隐式转换
  implicit def doubleToint(x:Double):Int = {
    println("double to int...")  //每调用一次函数就输出一次
    x.toInt
  }
  
  def main(args: Array[String]): Unit = {
    var i :Int = 1
    var d :Double = 1.1
    
    i = d //把 double 转换成 int 
    i = 100.1
    i = 2.1
  }
}

运行结果如图:

image.png

隐式参数

在写代码的过程中,有一个原则:尽量不要修改之前的代码

在开发过程中,如果预判一个参数将来会变动,就可以把它设置成implicit

注意:在修改隐式参数的值的时候,前面定义的变量名不重要,类型 要与函数类型一致

package imp
object imp02 {

  implicit val defaultPassword:String = "88888888"  // 2.修改默认密码为88888888

   def reg(name:String)(implicit password:String="123456"): Unit = {  // 1.默认密码为123456
      println(s"您注册成功,姓名:${name},密码:${password}")
   }

  def main(args: Array[String]): Unit = {

    reg("小花") // 没有传入密码,使用默认值
    reg("小白")("admin")

  }
}

隐式转换规则

1.无歧义规则

不能重新定义两个相同的转换函数

object imp03 {

  implicit def fun1(a:String):Int = a.toInt 
   
  def main(args: Array[String]): Unit = {

    val i:Int = "100" 
  }
}    
    
2.不能多次转换

例:在一次转换中, 千米->百米 ,百米->米,但是不能直接千米->米

package imp

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}米"}

  implicit def km2bm(km:KM):BM = new BM(km.value*10)
  implicit def bm2m(bm:BM):M = new M(bm.value*100)
//implicit def km2m(km:KM):M = new M(km.value*1000) 加上这句就可以转换

  def main(args: Array[String]): Unit = {

    val km = new KM(1.1)
    val bm:BM = km
    println(km) //1.1千米
    println(bm)  //11.0百米

   val m:M = bm
    println(m)  //1100.0米


// val m1:M = new KM(2) 报错!
 
  }
}

在实际的操作过程中,我们建议把它定义在如下两个地方:

1.包对象。这样在这个包下的所有类和对象中都可以使用,并且不需要额外的引入语句。

  1. 一个单独的文件定义中。这样在其他需要的位置就可以直接导入,然后使用。
package implictions

object implications {
  implicit def doubleToInt(x:Double):Int = {
    println("double to int...")
    x.toInt
  }
}

在需要的文件中导入,输入以下代码:

import implictions.implications._

屏幕截图 2025-12-29 101620.png