Scala中的 隐式转换 与示例代码

隐式转换函数指的是以implicit关键字声明的带有单个参数的函数。这样的函数将被自动应用,将值以一种类型转换成另一种类型。隐式转换函数通常不会由用户手动调用,而是由Sacala进行调用。如果要进行隐式转换,则需要对隐式转换函数进行导入(import)。因此通常建议将饮食转换函数的名称命名为"one2one"的形式。

常用使用方式

  • 隐式值
  • 隐式参数
  • 参数的隐式转换
  • 隐式类

Scala会考虑如下位置的隐式转换函数

  • 位于源或目标类型的伴生对象中的隐式函数
  • 位于当前作用域可以以单个标识符指代的隐式函数

隐式转换在如下三种不同情况下会被考虑

  • 当表达式类型与预期类型不同时
  • 当对象访问一个不存在成员时
  • 当对象调用某个方法,而这个方法的参数声明与传入参数不匹配时

有三种情况编译器不会尝试使用隐式转换

  • 如果代码能够在不适用隐式转换的前提下通过编译,则不会使用隐式转换
  • 编译器不会尝试同时执行多个转换
  • 存在二义性的转换是错误

隐式值

类易于缺省值

def ImplicitConvertExample{
	//声明值(缺省值)
	implicit val name : String ="zs"

	implicit val age : Int = 10

	def main(args: Array[String]):Unit = {
		//获取隐式值 implicitly[泛型]
		val iName = implicitly[String]
		val iAge = implicitly[Int]

		println(iName + "|" +iAge)
	}
}

注意:同类型的隐式值只能有一个

隐式参数

将方法或者函数的形参生命为implicit,要求在源文件中提供同类型的隐式值(缺省值或者默认值)

object ImplicitConverExample{
	//声明值(缺省值)
	implicit val name: String ="zs"

	implicit val y: Int = 10

	def main(args: Array[String]): Unit={
		// 获取隐式值 implicitly[泛型]

		sayHi
		sayHi("ls")

		println(sum(10))
		println(sum(10)(20))
	}

	//implicit 形参参数 调用sayHi 可以不给形参iName赋值,会自动寻找是否有同类型的隐式值存在
	//隐式转换:当编译不通过时 会触发隐式转换处理
	def sayHi(implicit iName: String):Unit = {
		println("hi:" + iName)
	}
	def sum(x : Int)(implicit y : Int): Int = {
		x + y
	}
}

参数的隐式转换(隐式转换函数)

 object ImplicitConvertExample01 {
  def main(args: Array[String]): Unit = {
    // 正常操作
    // sayHi(new Student("zs"))

    // say要求的类型是 Student 而传递是 String
    // 编译不通过时 自动触发 提供一个隐式转换函数 str ---> Student
    sayHi("zs")

  }

  // 隐式转换函数
  // one2one
  implicit def str2Student(str: String): Student = {
    println("--------------")
    new Student(str)
  }

  def sayHi(stu: Student): Unit = {
    println("学生的姓名:" + stu.name)
  }
}

class Student(var name: String) {

}
object ImplicitConvertExample02 {
  def main(args: Array[String]): Unit = {
    val man = new Man("zs")
    // man类中没有提供fly方法,会编译出错
    // 定义隐式转换函数  在编译不通过时将man类型自动转换为superMan 实现fly方法调用
    man.fly
  }

  implicit def man2SuperMan(man: Man): SuperMan = {
    new SuperMan(man.name)
  }
}

class Man(var name: String)

class SuperMan(var name: String) {

  def fly {
    println("flying....")
  }
}

隐式类

通过隐式类构造方法实现隐式转换的处理

object ImplicitConvertExample03 {
  def main(args: Array[String]): Unit = {
    val man2 = new Man2("zs")
    // man类中并没有提供fly方法,会编译出错
    // 定义隐式转换函数  在编译不通过时将man类型自动转换为superMan 实现fly方法调用
    man2.fly

    // 隐式类方式实现
    implicit class SuperMan2(man2: Man2) { // Man2 ---> SuperMan2
      var name: String = _

      def fly = {
        this.name = man2.name

        println("flying ...")
      }
    }
  }
}

class Man2(var name: String)

注意

  • 隐式类只能在特质,类,对象内部定义,不能独立声明
  • 隐式类构造函数只能携带一个非隐式参数
  • implicit关键字不能应用于scala case类

通过隐式转换实现Java集合和Scala集合的互操作↓

object ImplicitConvertExample04 {
  def main(args: Array[String]): Unit = {

    val list1: java.util.ArrayList[String] = new util.ArrayList[String]();
    list1.add("a")
    list1.add("b")
    list1.add("c")

    
    val scalaCollection = list1.asScala

    val newCollection = scalaCollection :+ "d" // scala操作方法

    println(newCollection.mkString(","))


    val javaList = newCollection.asJava
    javaList.add("e")
    }
}

如何导入外部的隐式转换

object ImplicitConvertExample02 {
  def main(args: Array[String]): Unit = {
    val man3 = new Man3("zs")
    // 如果:
    // 1. 隐式转换定义在类class中,需要通过import 导入隐式转换,具体方法是 先创建类 然后通过的类的引用名._
    // import man3._
    // man3.fly
    // 2. 隐式转换定义在对象object中,需要通过import导入隐式转换 具体方法是:import 单例对象._

    import TestAA._
    man3.fly
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值