快捷搜索:  汽车  科技

什么是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提供的隐式转换函数

Scala的隐式转换无处不在。在实际开发过程中,常常会自动地使用隐式转换。

比如,在for循环中构造循环语句:

什么是scala的隐式转换(Scala隐式转换入门实践)(1)

其实是方法调用,即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隐式转换入门实践)(2)

正是这些隐式转换函数的存在,简化了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-类型不匹配。

什么是scala的隐式转换(Scala隐式转换入门实践)(3)

我们定义一个隐式函数做一个隐式转换:

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 “ ”】,如图所示,可以看到自动调用了隐私转换函数。

什么是scala的隐式转换(Scala隐式转换入门实践)(4)

关闭Implicit conversions 提示的快捷键:Ctrl Alt Shift “-”

需要注意:如果在当前作用域范围存在函数签名相同,但函数名称不同的两个隐式转换函数,则在进行隐式转换时会报错。

有兴趣,可以再定义一个Double转换成Int类的隐式转换函数。

什么是scala的隐式转换(Scala隐式转换入门实践)(5)

三、隐式参数和隐式值

使用implicit关键字修改函数参数,这种形式的参数为隐式参数。

scala> def person(implicit name : String) = name //name为隐式参数

此时,直接调用person方法,编译器说无法为参数name找到一个隐式值。

什么是scala的隐式转换(Scala隐式转换入门实践)(6)

定义一个隐式值后再调用person方法:

scala> implicit val p="jack"

p: String = jack

scala> person

res5: String = jack

将变量p标记为 implicit,编译器会在方法省略隐式参数的情况下,去搜索作用域内的隐式值作为参数传入。

如果此时我们再定义一个隐式变量,调用方法时就会报错:ambiguous implicit values。

什么是scala的隐式转换(Scala隐式转换入门实践)(7)

隐式转换必须满足无歧义规则,在声明隐式参数的类型是最好使用特别的或自定义的数据类型,不要使用Int、String这些常用类型,避免碰巧匹配。

猜您喜欢: