scala中的隐式转换和隐式参数讲解与实践

举报
橙子园 发表于 2022/06/12 17:20:47 2022/06/12
【摘要】 Scala提供的隐式转换和隐式参数功能,是非常有特色的功能。是Java等编程语言所没有的功能。它可以允许你手动指定将某种类型的对象转换成其他类型的对象,或是给一个类增加方法。通过这些功能,可以实现非常强大的功能。

简介:

Scala提供的隐式转换和隐式参数功能,是非常有特色的功能。是Java等编程语言所没有的功能。它可以允许你手动指定将某种类型的对象转换成其他类型的对象,或是给一个类增加方法。通过这些功能,可以实现非常强大的功能。

1、隐式转换

隐式转换其核心就是定义一个使用 implicit 关键字修饰的方法,实现把一个原始类转换成目标类,这样你可以调用目标类中的方法,是不是很强大。隐式转换的方法需要定义在一个object中。

示例一:对第三方库类进行转化,让File类具备RichFile类中的read方法
import java.io.File

import scala.io.Source

object ExecFileDef {
  //定义一个隐式转换的方法,实现把File转换成RichFile
  implicit def file2RichFile(file: File) = new RichFile(file)
}

// 扩展file类
class RichFile(val file: File){
  //读取数据文件的方法
  def read():String={
    Source.fromFile(file).mkString
  }
}

object RichFile{
  def main(args: Array[String]): Unit = {
    //1、构建一个File对象
    val file = new File("F:\\acc.txt")

    //2、手动导入隐式转换
    import ExecFileDef.file2RichFile

    //此时的file已经被转化了, 可以使用read方法
    val data: String = file.read
    println(data)
  }
}
示例二:对自己定义的类使用隐式转换,普通人成为大佬
class AveragePerson(val name: String)


class Mogul(val name: String) {
  def come(): Unit = {
    println("大佬 "+ name + " 来了,掌声想起,自带光环,疯狂撒钱!")
  }
}


object TransformExec {

  implicit def AveragePerson2Mogul(averagePerson: AveragePerson): Mogul = {
    new Mogul(averagePerson.name)
  }

  def main(args: Array[String]): Unit = {
    val mogul = new AveragePerson("橙子园")
    mogul.come()
  }
}

结果:

示例三:一个类隐式转换具有相同方法的类的情况
class A
class B(a: A) {
  def readBook(): Unit ={
    println("B读书")
  }
}

class C(a: A){
  def readBook(): Unit ={
    println("C读书")
  }
  def writeBook(): Unit ={
    println("C写书")
  }
}

object BC{

  //创建一个类转换为2个类的隐式转换
  implicit def A2B(a: A)=new B(a)
  implicit def A2C(a: A)=new C(a)
}

object C{
  def main(args: Array[String]) {
    //导包
    //import BC._ 这会将AB类下的所有隐式转换导进来
    //import BC.A2B 只导入A类到B类的的隐式转换方法
    //import BC.A2C 只导入A类到C类的的隐式转换方法


    import BC._
    val a = new A

    //由于B类与C类中都有readBook(),只能导入其中一个,否则调用共同方法时代码报错
    //a.readBook()

    //A类可以执行C类中的writeBook()
    a.writeBook()

  }
}

结果:

2、隐式参数

它是指在函数或者方法中,定义一个用implicit修饰的参数,此时Scala会尝试找到一个指定类型的用implicit修饰的参数,即隐式值,并注入参数。隐式参数也需要定义在一个object中。

示例:隐式参数的使用,老板给员工发钱
object Company{
  //注意:同一类型的隐式值只允许出现一次,否则会报错
  implicit val name: String = "橙子园"
  implicit val salary: Double = 100000.0
  //再次出现会报错
  //implicit  val zzz: String="橙子猿"

}

class Boss {
  //定义一个用implicit修饰的参数类型为String
  //注意参数匹配的类型,它需要的是String类型的隐式值
  def callName(implicit name: String): String={
    name
  }

  //定义一个用implicit修饰的参数,类型为Double
  //注意参数匹配的类型,它需要的是Double类型的隐式值
  def getMoney(implicit money: Double): String={
    money.toString
  }

}

object Boss extends App{
  //使用import导入定义好的隐式值,注意:必须先加载否则会报错
  import Company.name
  import Company.salary

  val boss = new Boss
  println(boss.callName + ":" + boss.getMoney)

}

结果:

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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