scala隐式详解

使用implicit 修饰的内容是隐式内容, 隐式的特点就是遇到适应的类型会自动的应用

意义:

  • 使得静态类型动态化
  • 为现有类库添加功能
  • 隐式的代理增强一个类或者一个方法

分类:

  • 隐式参数
  • 隐式函数
  • 隐式类 

隐式变量

定义隐式变量 
object MyValue {
  implicit  val  age:Int = 19
  implicit  val name:String = "lisi"
}

定义隐式变量 
/**
  * 这个方法的所有的参数是隐式参数
  * 可以使用柯里化来定义个别的隐式参数 
  * add(x:Int)(implicit y:Int , z:Int)
  *    上面的例子中x为正常参数 y z都为隐式参数
  * @param name
  * @param age
  */
def myShow(implicit name: String, age: Int): Unit = {
  println(name + "   " + age)
}

演示现象
def main(args: Array[String]): Unit = {
  new Show().myShow("reba",12)
  // 导入了隐式参数  就会从context中寻找隐式数据
  // context中只能有一个匹配类型的数据
  // 如果找到多个匹配类型的数据就会报错
 import  MyValue._
  //lisi   19
  new Show().myShow
}


应用示例
class A[T] {
 def mymax1(x:T ,y:T): T ={
    if(x > y) x else y// T类型中没有定义>方法  报错
  }
 // T类型必须是可以隐式的转换成Ordered的类型  , 这个隐式转换要事先定义
  def mymax2(x:T ,y:T)(implicit order:T=>Ordered[T]): T ={
    if(x > y) x else y
  }
}
object  A{
  def main(args: Array[String]): Unit = {
    // Int已经默认的实现了 Orderd的实时转换 
    val res: Int = new A[Int]().mymax2(12,34)
    println(res)
  }
}

隐式函数

函数处理的数据类型 =>  返回的数据类型 , 当遇到对应的类型=>类型处理的时候隐式函数会自动的应用

增强一个类

添加不存在的函数,implicit作用于函数,称之为隐式函数

定义一个类只有add的方法
  * 2019/11/12
  * 定义一个类 类中定义一个方法
  *
  * @author Hangge.z  WX:17710299606
  *         想对类增强一些方法
  *
  */
class Demo {
  val add = (x: Int, y: Int) => {
    x + y
  }
}
定义一个增强的类
/**
  * 增强类
  *   定义一个减法方法
  * @param demo
  */
class Advice(val demo: Demo) {
  val substract = (x: Int, y: Int) => {
    x - y
  }
}
编写一个隐式转换的方法类
/**
  * 将Demo类隐式转换成增强的类
这样我们被增强的类既有自己的方法也有增强类的方法
这样就实现的了隐式函数对一个类增强的目的
  */
object ImplicitAdvice {
//将Demo类隐式转换成增强类   实现对Demo类增强的目的
  implicit def advice(demo: Demo) = {
    new Advice(demo)
  }
}
演示
object Test2 {
  def main(args: Array[String]): Unit = {
    val demo = new Demo
     //在这里调用没有substract方法
    val sum: Int = demo.add(1,2)
    import  ImplicitAdvice._
    val res2: Int = demo.substract(33,20)
    println(sum)
    println(res2)
  }
}

隐式类

增强一个类型

隐式类约束

隐式类必须有一个带一个参数的主构造函数

必须定义在另一个class/object/trait里面(不能独立定义)

隐式类构造器只能带一个不是implicit修饰的参数

作用域中不能有与隐式类类型相同的成员变量,函数以及object名称

定义一个类
class B {
  val add = (x: Int, y: Int) => {
    x + y
  }
}
定义一个隐式类
/**
  * 隐式主题类
  */
object ImplicitContext{
//隐式类只能对一种类型的类进行增强  B类或者子类增强
  implicit  class RichB(b:B){
    def multiply(x: Int, y: Int) = {
      x * y
    }
  }
}
演示增强效果
def main(args: Array[String]): Unit = {
  val b = new B   // B类  以及他的子类
  println(b.add(12, 12))
  import ImplicitContext._
  println(b.multiply(12, 12))
}

注意

如果代码无需隐式转换即可通过编译,则不会引入隐式转换

隐式转换只会匹配一次,即隐式转换至多发生一次

存在二义性的隐式转换报错,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值