scala隐式转换

Scala提供的隐式转换的特性的作用,简单说就是:当Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出合适的类型,在代码重构设计上,可以避免冗余的代码,使得代码非常优雅。

    使用场景一:隐式参数

scala>  def sayHello(age: Int)(implicit name: String) = println("my name is:" + name + ",my age is:" + age)
sayHello: (age: Int)(implicit name: String)Unit

scala> implicit val name = "cyony"
name: String = cyony

scala> sayHello(25)
my name is:cyony,my age is:25

 

    sayHello函数有两个参数,其中name为隐式参数,在实际调用中不需要显示传入这个参数,但是在作用域范围内必须声明一个String类型的隐式变量,这样在调用的时候,会自动传入这个变量。PS:如果在同一个作用域内定义了两个同类型的隐式变量,则会有冲突。

    隐式参数的作用域范围有两个:一种是当前作用域内可见的val或者var定义的隐式变量;一种是隐式参数类型的伴生对象内的隐式值。

复制代码
scala> implicit val name1 = "cyony1"
name1: String = cyony1

scala> sayHello(25)
<console>:16: error: ambiguous implicit values:
 both value name of type => String
 and value name2 of type => String
 match expected type String
       sayHello(25)
               ^
复制代码

 

    使用场景二:类型匹配

复制代码
scala> import scala.language.implicitConversions
import scala.language.implicitConversions
 
scala> implicit def int2Range(num : Int): Range = 1 to num
int2Range: (num: Int)Range
 
scala> def spreadNum(range: Range): String = range.mkString(",")
spreadNum: (range: Range)String
 
scala> spreadNum(5)
res0: String = 1,2,3,4,5
复制代码

  上面所示,spreadNum函数签名是个Range类型的参数,但是传入的值是一个Int类型的,所以编译器在作用域内找到了int2Range隐式转换函数,自动将int转换为range对象来适配。

  隐式转换的函数叫什么名字无所谓,因为实际调用中不会手动调用,但是如果需要使用隐式转换函数,需要import方式手动导入,才能被编译器寻找到。

    使用场景三:类型增强

复制代码
scala> class Man(val name: String)
defined class Man
 
scala> class SuperMan(val name: String) {
     |     def fly = println("you can fly")
     |   }
defined class SuperMan
 
scala>  implicit def man2SuperMan(man: Man): SuperMan = new SuperMan(man.name)
man2SuperMan: (man: Man)SuperMan
 
scala> val cyony = new Man("cyony")
cyony: Man = Man@63d3c9dc
 
scala> cyony.fly
you can fly
复制代码

  编译器在调用fly方法时,发现Man对象并没有这个函数,然后通过man2SuperMan隐式函数转换成SuperMan对象,进而调用他的fly函数,来实现类型增强功能。

       或者可以通过隐式类的方式来实现相同的功能,代码如下:

复制代码
scala> class Man(name: String)
defined class Man
 
scala> implicit class MyImplicitTypeConversion(val man: Man) {
     |     def fly = println("you can fly")
     |   }
defined class MyImplicitTypeConversion
 
scala> val cyony = new Man("cyony")
cyony: Man = Man@7412a438
 
scala> cyony.fly
you can fly
复制代码

    隐式转换的发生时机:

    1、调用某个函数,但是给函数传入的参数类型,与函数定义的签名不匹配。

    2、使用某个类型对象,调用某个方法,而这个方法并不存在于该类型时。

    3、使用某个类型对象,调用某个方法,虽然该类型有这个方法,但是给方法传入的参数类型与签名并不一致的时候。

 

转载博客:https://blog.csdn.net/cyony/article/details/79616013

posted @   guoyu1  阅读(292)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示