前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021年大数据常用语言Scala(三十八):scala高级用法 隐式转换和隐式参数

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

作者头像
Lansonli
发布2021-10-11 15:31:30
5690
发布2021-10-11 15:31:30
举报
文章被收录于专栏:Lansonli技术博客Lansonli技术博客

隐式转换和隐式参数

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

隐式转换

来看一个案例,

代码语言:javascript
复制
object SuperIntDemo {
  def main(args: Array[String]): Unit = {
    val a:Int = 1
// 使用中缀调用to方法
    println(a to 10)
  }
}

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

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

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

隐式转换的使用步骤:

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

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

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

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

代码语言:javascript
复制
class RichFile(val f:File) {
  // 将文件中内容读取成字符串
  def read() = Source.fromFile(f).mkString
}

object MyPredef {
  // 定义隐式转换方法
  implicit def file2RichFile(f:File) = new RichFile(f)
}

object ImplicitConvertDemo {

  def main(args: Array[String]): Unit = {
    val f = new File("./data/textfiles/1.txt")
    
    // 导入隐式准换
    import MyPredef.file2RichFile
    // 调用的其实是RichFile的read方法
    println(f.read())
  }
}

自动导入隐式转换方法

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

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

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

代码语言:javascript
复制
class RichFile(val f:File) {
  // 将文件中内容读取成字符串
  def read() = Source.fromFile(f).mkString
}

object ImplicitConvertDemo {
  // 定义隐式转换方法
  implicit def file2RichFile(f:File) = new RichFile(f)

  def main(args: Array[String]): Unit = {
    val f = new File("./data/textfiles/1.txt")

    // 调用的其实是RichFile的read方法
    println(f.read())
  }
}

隐式转换的时机

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

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

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

示例:

代码语言:javascript
复制
object ImplicitConvertDemo {
  // 定义隐式转换方法
  implicit def file2RichFile(f:File) = new RichFile(f)

  def main(args: Array[String]): Unit = {
    val f = new File("./data/textfiles/1.txt")

    // test1接收的参数类型为Rich,此时也自动进行了隐式转换
    test1(f)
  }

  def test1(r:RichFile) = println(r.read())
}

隐式参数

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

定义隐式参数:

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

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

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

示例:

代码语言:javascript
复制
// 定义一个分隔符类
case class Delimiters(left:String, right:String)

object MyPredef1 {
  implicit val quoteDelimiters = Delimiters("<<<", ">>>")
}

object ImplicitParamDemo {

  // 使用分隔符将想要引用的字符串括起来
  def quote(what:String)(implicit delims:Delimiters) = delims.left + what + delims.right

  def main(args: Array[String]): Unit = {
    println(quote("hello, world")(Delimiters("<<", ">>")))

    // 手动导入
    import MyPredef1._
    println(quote("hello, world"))
  }
}

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-05-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 隐式转换和隐式参数
    • 隐式转换
      • 自动导入隐式转换方法
        • 隐式转换的时机
          • 隐式参数
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档