scala教程:隐式转换-隐式值(隐式变量)(implicit)

介绍

隐式值也叫隐式变量,作用:相当于 形参的默认值,调用 方法 或 函数 时,可以不传值

与形参默认值的区别

形参的默认值 只能作用于 一个 方法 或 函数

隐式值可以作用于 多个 方法 或 函数 的形参

实现步骤

  1. 将 方法 或 函数 的 形参 标记为 implicit
  2. 用 implicit 修饰变量
  3. 调用 方法 或 函数 时,可 省略参数 ,编译器会搜索作用域内的 隐式变量 作为 参数

案例

用于函数

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

  def study(implicit str: String): Unit = {
    println("学习 "+str)
  }
  implicit val str1: String = "英语"

  //study("数学") //正常调用
  //    study() //报错,不能加上()
  study //调用时,如果不传值,不能带(),否则报错

}

注意: 此处调用时,如果不传值,不能带 (),否则报错

解释: 调用 study 函数时,编译器根据 形参类型,自动查找 与该类型相匹配、且由 implicit 修饰的变量

用于方法

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

  implicit val str1: String = "英语"

  //study("数学") //正常调用
  study //调用时,如果不传值,不能带(),否则报错
}

def study(implicit str: String): Unit = {
  println("学习 "+str)
}

案例:形参有默认值时

形参有默认值 且 有隐式变量时

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

  def study(implicit str: String = "数学"): Unit = {
    println("学习 "+str)
  }
  implicit val str1: String = "英语"

  //study("语文") //正常调用
  study() //调用时,有(),传入的是形参默认值
  study //调用时,没有(),传入的是隐式变量
}

总结:

  • 调用时,有 (),传入的是形参默认值
  • 调用时,没有 (),传入的是隐式变量

类型不匹配时

隐式形参有默认值 且 有隐式变量,但是 类型不匹配 时,传入的是 形参默认值

如下:

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

  def study(implicit str: String = "数学"): Unit = {
    println("学习 "+str)
  }
  implicit val i: Int = 100

  study("语文") //正常调用
  study() //有(),调用时,传入的是形参默认值
  study //调用时,不带(),由于隐式变量类型 与 形参类型不匹配,传入的是形参默认值

}

总结: 由于 隐式参数的类型 与 隐式变量的类型 不匹配,调用函数,传入的是 形参默认值

其他写法

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

  implicit val str1: String = "英语"

  //函数后面要有 ()
  def study()(implicit str: String): Unit = {
    println("学习 "+str)
  }
  study() //调用时,带() 或 不带() 都可以
}

注意: 调用时带上 ()

应用场景

spark 的 takeOrdered 算子

def takeOrdered(num: Int)(implicit ord: Ordering[T]): Array[T]

常见错误

有 隐式参数,没有 隐式变量

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

  def study(implicit str: String): Unit = {
    println("学习 "+str)
  }
  study
//  study("数学")
}

解决方法,调用函数时传值,如下:

study("数学")

隐式参数 类型 与 隐式变量 不匹配

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

  implicit val str1: Int = 10

  def study(implicit str: String): Unit = {
    println("学习 "+str)
  }
  study
  //  study("数学")
}

解决方法,调用函数时传值,如下:

study("数学")

不能匹配多个隐式变量

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

  implicit val str1: String = "英语"
  implicit val str2: String = "数学"

  def study(implicit str: String): Unit = {
    println("学习 "+str)
  }
  study //调用时,不能带()
}

执行报错,因为调用 study 函数时,是根据 隐式参数的类型 匹配 隐式变量的,此时 有2个同类型的隐式变量,编译器 不知道调用哪个,所以报错


原文出处:/show_1IX1L1LawtfG.html