介绍
隐式值也叫隐式变量,作用:相当于 形参的默认值,调用 方法 或 函数 时,可以不传值
与形参默认值的区别
形参的默认值 只能作用于 一个 方法 或 函数
隐式值可以作用于 多个 方法 或 函数 的形参
实现步骤
- 将 方法 或 函数 的 形参 标记为
implicit - 用
implicit修饰变量 - 调用 方法 或 函数 时,可 省略参数 ,编译器会搜索作用域内的 隐式变量 作为 参数
案例
用于函数
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个同类型的隐式变量,编译器 不知道调用哪个,所以报错
