2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数

举报
Lansonli 发表于 2021/09/29 01:09:43 2021/09/29
【摘要】 目录 隐式转换和隐式参数 隐式转换 自动导入隐式转换方法 隐式转换的时机 隐式参数 隐式转换和隐式参数 隐式转换和隐式参数是scala非常有特色的功能,也是Java等其他编程语言没有的功能。我们可以很方便地利用隐式转换来丰富现有类的功能。   隐式转换 来看一个案例, object Super...

目录

隐式转换和隐式参数

隐式转换

自动导入隐式转换方法

隐式转换的时机

隐式参数


隐式转换和隐式参数

隐式转换和隐式参数是scala非常有特色的功能,也是Java等其他编程语言没有的功能。我们可以很方便地利用隐式转换来丰富现有类的功能。

 

隐式转换

来看一个案例,


  
  1. object SuperIntDemo {
  2.   def main(args: Array[String]): Unit = {
  3.     val a:Int = 1
  4. // 使用中缀调用to方法
  5.     println(a to 10)
  6.   }
  7. }

通过查看Int的源代码,你会惊奇地发现,Int类型根本没有to方法。这难道是让人怀疑人生的大bug吗?

——这其实就是隐式转换的强(gui)大(yi)之处。它在背后偷偷摸摸地帮我们了某种类型转换。

所谓隐式转换,是指以implicit关键字声明的带有单个参数的方法。它是自动被调用的,自动将某种类型转换为另外一种类型。

隐式转换的使用步骤:

在object中定义隐式转换方法(使用implicit)

在需要用到隐式转换的地方,引入隐式转换(使用import)

自动调用隐式转化后的方法

示例:使用隐式转换,让File具备有reada


  
  1. class RichFile(val f:File) {
  2.   // 将文件中内容读取成字符串
  3.   def read() = Source.fromFile(f).mkString
  4. }
  5. object MyPredef {
  6.   // 定义隐式转换方法
  7.   implicit def file2RichFile(f:File) = new RichFile(f)
  8. }
  9. object ImplicitConvertDemo {
  10.   def main(args: Array[String]): Unit = {
  11.     val f = new File("./data/textfiles/1.txt")
  12.     
  13.     // 导入隐式准换
  14.     import MyPredef.file2RichFile
  15.     // 调用的其实是RichFile的read方法
  16.     println(f.read())
  17.   }
  18. }

 

自动导入隐式转换方法

前面,我们手动使用了import来导入隐式转换。是否可以不手动import呢?

在scala中,如果在当前作用域中有隐式转换方法,会自动导入隐式转换。

示例:将隐式转换方法定义在main所在的object中


  
  1. class RichFile(val f:File) {
  2.   // 将文件中内容读取成字符串
  3.   def read() = Source.fromFile(f).mkString
  4. }
  5. object ImplicitConvertDemo {
  6.   // 定义隐式转换方法
  7.   implicit def file2RichFile(f:File) = new RichFile(f)
  8.   def main(args: Array[String]): Unit = {
  9.     val f = new File("./data/textfiles/1.txt")
  10.     // 调用的其实是RichFile的read方法
  11.     println(f.read())
  12.   }
  13. }

 

隐式转换的时机

什么时候会自动执行隐式转换呢?

当对象调用中不存在的方法时,编译器会自动将对象进行隐式转换

当方法中的参数类型与目标类型不一致时

示例:


  
  1. object ImplicitConvertDemo {
  2.   // 定义隐式转换方法
  3.   implicit def file2RichFile(f:File) = new RichFile(f)
  4.   def main(args: Array[String]): Unit = {
  5.     val f = new File("./data/textfiles/1.txt")
  6.     // test1接收的参数类型为Rich,此时也自动进行了隐式转换
  7.     test1(f)
  8.   }
  9.   def test1(r:RichFile) = println(r.read())
  10. }

 

隐式参数

函数或方法可以带有一个标记为implicit的参数列表。这种情况,编译器会查找缺省值,提供给该方法。

定义隐式参数:

在方法后面添加一个参数列表,参数使用implicit修饰

在object中定义implicit修饰的隐式值

调用方法,可以不传入implicit修饰的参数列表,编译器会自动查找缺省值

示例:


  
  1. // 定义一个分隔符类
  2. case class Delimiters(left:String, right:String)
  3. object MyPredef1 {
  4.   implicit val quoteDelimiters = Delimiters("<<<"">>>")
  5. }
  6. object ImplicitParamDemo {
  7.   // 使用分隔符将想要引用的字符串括起来
  8.   def quote(what:String)(implicit delims:Delimiters) = delims.left + what + delims.right
  9.   def main(args: Array[String]): Unit = {
  10.     println(quote("hello, world")(Delimiters("<<"">>")))
  11.     // 手动导入
  12.     import MyPredef1._
  13.     println(quote("hello, world"))
  14.   }
  15. }

和隐式转换一样,可以使用import手动导入隐式参数

如果在当前作用域定义了隐式值,会自动进行导入

文章来源: lansonli.blog.csdn.net,作者:Lansonli,版权归原作者所有,如需转载,请联系作者。

原文链接:lansonli.blog.csdn.net/article/details/116810840

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。