Scala 的隐式转换是一种自动类型转换机制,它可以在编译器自动插入一些代码,将一个类型自动转换成另一个类型。这种转换可以发生在函数调用、赋值、类型转换等多种场景中。
隐式转换的机制可以让 Scala 代码更加简洁、优雅。例如,我们可以通过隐式转换实现一些类型之间的转换,而不需要手动编写转换代码。
1 隐式函数
下面是一个简单的例子,展示了如何使用隐式转换将一个字符串转换成整数:
object TestImplicit {
def main(args: Array[String]): Unit = {
val i: Int = "123"
println(i)
}
implicit def StringtoInt(s: String): Int = {
Integer.parseInt(s)
}
}
将函数注释掉之后,IDEA也会进行报错,
2 隐式参数
普通方法或者函数中的参数可以通过 implicit 关键字声明为隐式参数,调用该方法时, 就可以传入该参数,编译器会在相应的作用域寻找符合条件的隐式值。
- 同一个作用域中,相同类型的隐式值只能有一个
- 编译器按照隐式参数的类型去寻找对应类型的隐式值,与隐式值的名称无关。
- 隐式参数优先于默认参数
implicit val str: String = "辰辰"
def hello()(implicit arg: String = "cc") = println(arg)
def main(args: Array[String]): Unit = {
hello // 辰辰
}
3 隐式类
在 Scala2.10 后提供了隐式类,可以使用 implicit 声明类,隐式类的非常强大,同样可以扩展类的功能,在集合中隐式类会发挥重要的作用。
- 其所带的构造参数有且只能有一个
- 隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是顶级的。
object TestImplicit {
implicit class StringExtensions(s: String) {
def increment: String = s.map(x => (x + 1).toChar)
}
def main(args: Array[String]): Unit = {
val str = "chen chen"
println(str.increment) // difo!difo
}
}
此隐式类扩展了 String
类型的功能,添加了一个名为 increment
的方法,该方法将字符串中的每个字符的 ASCII 值加 1,并返回新的字符串
4 隐式机制解析
编译器查找顺序
- 首先会在当前代码作用域下查找隐式实体(隐式方法、隐式类、隐式对象)。( 一般是这种情况)
- 如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。类型的作用域是指与该类型相关联的全部伴生对象以及该类型所在包的包对象。
需要注意的是,隐式转换可能会导致一些意想不到的行为,因此在使用隐式转换时,我们需要谨慎地考虑其可能带来的影响。