简介
所谓隐式函数指的是那种以implicit关键字声明的带有单个参数的函数。正如它的名称所表达的,这样的函数将会自动应用,将值从一种类型转换为另一种类型。
隐式函数的使用
需求分析:使用隐式函数解决数据类型的转换问题
object ImplicitDemo01 {
def main(args: Array[String]): Unit = {
// 编写一个隐式函数将Double =》 Int
implicit def douToInt(d: Double): Int = {
d.toInt
}
val num: Int = 3.9
println(num)
}
}
这里隐式函数的使用就是将Double类型的3.9隐式的转化为Int类型,在当前的这个作用域中,它会默认的调用 douToInt 这个函数。
注意事项以及细节处理
- 隐式函数的函数名是可以任意的,隐式函数与函数名称无关。
- 隐式函数在当前作用域中可以有多个,但是只有一个隐式函数能够被识别。
隐式转换丰富类库功能
1.首先可以定义一个经过丰富的类型,提供你想要的功能
implicit def addDelete(mysql: Mysql): DB = {
new DB
}
class DB {
def delete(): Unit = {
println("delete")
}
}
2.然后就可以在本身功能的基础上实现上面的功能
class Mysql {
def insert(): Unit = {
println("insert")
}
}
val mysql = new Mysql
mysql.insert()
mysql.delete() //调用了隐式函数
隐式值,默认值,传值的优先级
当我们在一个程序中同时出现隐式值,默认值,传值的情况时它们是有优先级进行区分的。
// 隐式值
implicit val name: String = "Scala"
// 默认值
def hello(implicit content: String = "jack"): Unit = {
println("Hello " + content)
}
hello("wc") // 传值
隐式值,默认值,传值同时存在的情况下输出:Hello wc
// 隐式值
implicit val name: String = "Scala"
// 默认值
def hello(implicit content: String = "jack"): Unit = {
println("Hello " + content)
}
hello
隐式值,默认值同时存在时输出:Hello Scala
小结:
- 编译器的优先级为 传值 > 隐式值 > 默认值
- 在隐式值匹配时,不能有二义性
- 如果 隐式值,默认值,传值 一个都没有,就会报错
隐式类的使用
代码样例
object ImplicitClassDemo {
def main(args: Array[String]): Unit = {
// DB1是一个隐式类
implicit class DB1(val m: Mysql1) {
def addSuffix(): Unit = {
println(m + "scala")
}
}
val mysql = new Mysql1
mysql.sayOk()
mysql.addSuffix()
}
}
class DB1{}
class Mysql1{
def sayOk(): Unit = {
println("sayOk")
}
}
注意事项
- 其所带的构造参数有且只能有一个
- 隐式类必须被定义在 “类”,“伴生对象”,“包对象”里。
- 隐式类不能是样例类
- 作用域内不能有与之相同名称的标识符