scala的隐式转换 || 实例详解

定义:
当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转化提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型。


                               隐式参数
 (1)先看一下这个程序的运行结果
object ImplicitParam {
implicit  val xxx = 777

  def  test(implicit i:Int = 100) = {
    println(i)
  }

  def main(args: Array[String]): Unit = {
    test
  }
}

结果呢:是777,有点不可思议吧。看一下解析

**
  * 隐式参数
  * 柯里化方法
  * implicit 关键字表示隐式的,用implicit关键字修饰的变量叫隐式变量
  * 用implicit修饰的方法叫隐式方法
  * 步骤解析:
  *   1:方法在执行时,发现需要一个隐式的intimplicit i:Int)类型参数,就会在方法执行的环境中(context)中跟
  *   2:方法中依赖的隐式变量类型一致的参数,如果有就使用
  *       implicit val xxx = 777
  *   3:如果没有就使用默认值
  *       def test()(implicit i:Int = 200) = {
  *   4:如果没有默认值,就报错
  *       def test()(implicit i:Int) = {
  *   优先级: 传入-》上下文中类型一直的隐式值-》默认值
  *   注意:
  *     implicit val abc = 888
  *     使用多个隐式变量会报错
  *
  */

                      隐式转换类
/**
  * 隐式转换类
  */
object ImplicitClassDemo {

  //实现计算功能
  implicit  class  Cala(x:Int){
    def  add (y:Int) = x + y
  }

  def main(args: Array[String]): Unit = {
    //实现两个数字的相加
    /**
      * 调用过程:
      *   1:调用1的add函数,但是没有发现add函数
      *   2:查找一个能否接受int类型的隐式类,->  implicit class Cala(x:Int) {
      *   3:把1传递给Cala对象,构造一个Cala对象
      *   4:再调用Cala对象的add函数
      */
    println("两个数字的和:"+ 1.add(4))
    println("两个数字的和:"+Cala(7).add(4))
  }
}


----------


        隐式转换函数


      1) 隐式转换函数的函数名可以是任意的,与函数名称无关,只与函数签名(函数参数和返回值类型)有关。
      2)如果当前作用域中存在函数签名相同但函数名称不同的两个隐式转换函数,则在进行隐式转换时会报错。    



/*
隐式转换函数
 */

/**
  * 定义一个水果类
  * @param name
  */
class Fruit(name:String){
  def getName() ={
    name
  }
}

/**
  * 猴子类,喜欢吃水果
  * @param f
  */
class Monkey(f:Fruit){
  def say() = println(s"Monkey like ${f.getName()}")
}

object ImplicitDemo {

  /**
    * 定义一个转换规则(隐式转换函数),把Fruit转换成Monkey
    * @param f
    * @return
    */
  implicit  def Fruit2Monkey(f:Fruit):Monkey = {
    new Monkey(f)
  }
  def main(args: Array[String]): Unit = {
    //定义一个水果对象
    val f: Fruit = new Fruit("桃子") //调用这个函数
    f.say()
  }
}



----------


           使用柯里化传入一个隐式转换函数

**
  * Created by zhangjingcun on 2018/9/15 10:10.
  */
class  Girl (val name:String, var faceValue:Int){}

object MyPreDef{
  implicit object Girl2Ordering extends Ordering[Girl]{
    override def compare(x: Girl, y: Girl): Int = {
      x.faceValue - y.faceValue
    }
  }
}
class MissR[T] {

  /**
    * 如何使用柯里化传入一个隐式转换函数,作用和ViewBound是一样的,都需要一个隐式转换方法或者函数
    * 核心:使用柯里化的方式实现了类似视图界定的功能
    *   解析:
    *     (implicit ord: T => Ordered[T]) 是一个函数
    *     实现了Ordered特质
    *   调用:
    *     val g = mr.choose(g1, g2)
    *
    * @param frist
    * @param second
    * @return
    */
    //这一行自动传入了一个隐式函数
  def choose(frist:T, second:T)(implicit ord: T => Ordered[T]):T ={
    if(frist > second) frist else second
  }
}

object MissR{
  def main(args: Array[String]): Unit = {
    import MyPreDef._

    val mr = new MissR[Girl]
    val g1 = new Girl("mike", 90)
    val g2 = new Girl("mary", 92)

    val g = mr.choose(g1, g2)
    println(g.name)
  }
}

猜你喜欢

转载自blog.csdn.net/qq_41166135/article/details/82720951