什么是scala的隐式转换(Scala隐式转换入门实践)
什么是scala的隐式转换(Scala隐式转换入门实践)在特定条件下,会自动调用Scala提供的隐式转换函数来完成隐式转换,但是Scala提供的隐式转换函数毕竟是有限的。下面我们自己定义一个简单的隐式转换函数。正是这些隐式转换函数的存在,简化了Scala程序代码,使代码更加简洁。def to(end : scala.Int) : scala.collection.immutable.Range.Inclusive = { /* compiled code */ }Int类型到RichInt类型的转换定义在scal.LowPriorityImplicits 类中,可以通过如下的命令查看:scala> :implicit -v
隐式转换(Implicit Conversion)是Scala语言提供的一个强大的语法特性,是学习Scala必须要掌握的技能。
Scala的隐式转换无处不在。在实际开发过程中,常常会自动地使用隐式转换。
比如,在for循环中构造循环语句:
其实是方法调用,即1.to(5),但Int类型并没有to方法,在执行时会自动进行隐式转换,将Int类型转换为scala.runtime.RichInt类型。
def to(end : scala.Int) : scala.collection.immutable.Range.Inclusive = { /* compiled code */ }
Int类型到RichInt类型的转换定义在scal.LowPriorityImplicits 类中,可以通过如下的命令查看:
scala> :implicit -v
正是这些隐式转换函数的存在,简化了Scala程序代码,使代码更加简洁。
二、自定义隐式转换函数在特定条件下,会自动调用Scala提供的隐式转换函数来完成隐式转换,但是Scala提供的隐式转换函数毕竟是有限的。下面我们自己定义一个简单的隐式转换函数。
看一个示例:
package implicitconversion
import scala.collection.immutable.StringOps
object ImplicitTest {
def plus(a:Int b:Int)={
a b
}
def main(args: Array[String]): Unit = {
println(plus(1 2))
}
}
输出结果为:3
但是,如果我们想让字符串“1”和字符串“2”相加呢:
println(plus("1" "2"))
就会出现如下错误:type mismatch-类型不匹配。
我们定义一个隐式函数做一个隐式转换:
implicit def str2Int(x:String):Int = new StringOps(x).toInt
直接把String转换为Int类型。
再次执行:println(plus("1" "2"))
就工作正常了。编译器发现传入参数的类型与plus方法定义的类型不匹配,就会在当前作用域范围内查找能够将字符串String转换成Int类型的隐式转换函数。代码中定义隐式转换函数:str2Int(x:String):Int 正好满足要求。
在IDEA 编辑器中,打开Implicit conversions提示【快捷键:Ctrl Alt Shift “ ”】,如图所示,可以看到自动调用了隐私转换函数。
关闭Implicit conversions 提示的快捷键:Ctrl Alt Shift “-”
需要注意:如果在当前作用域范围存在函数签名相同,但函数名称不同的两个隐式转换函数,则在进行隐式转换时会报错。
有兴趣,可以再定义一个Double转换成Int类的隐式转换函数。
使用implicit关键字修改函数参数,这种形式的参数为隐式参数。
scala> def person(implicit name : String) = name //name为隐式参数
此时,直接调用person方法,编译器说无法为参数name找到一个隐式值。
定义一个隐式值后再调用person方法:
scala> implicit val p="jack"
p: String = jack
scala> person
res5: String = jack
将变量p标记为 implicit,编译器会在方法省略隐式参数的情况下,去搜索作用域内的隐式值作为参数传入。
如果此时我们再定义一个隐式变量,调用方法时就会报错:ambiguous implicit values。
隐式转换必须满足无歧义规则,在声明隐式参数的类型是最好使用特别的或自定义的数据类型,不要使用Int、String这些常用类型,避免碰巧匹配。