Scala 隐式转换

Scala 隐式转换

当编译器第一次编译失败的时候,会在当前的环境中查找能让代码编译通过的方法,用于将类型进行转换,实现二次编译

一、隐式函数

隐式转换可以在不需修改任何代码的情况下,扩展某个类的功能
定义了隐式函数,就不需要在那个main方法里创建一个对象进行调用,直接就可以进行调用了

package Scala05_yichang
// implicit 隐式转换
class test02_implicit {

}
object test02_implicit{
  def main(args: Array[String]): Unit = {
    val a = new MyRichInt(12)
    println(a.myMax(15)) //做一个比较,15比12大输出的就是15


    //1、隐式函数
    implicit def convert(num:Int):MyRichInt = new MyRichInt(num)
    println(12.myMax(15)) //这个调用要放在隐式函数下面,因为这才是他的作用域

    println("===================")
    //2、隐式类
    implicit class MyRichInt2(val self:Int){ //这个隐式类必须要放在一个类或者对象里面。因为他不能是最顶级的
      // 自定义比较大小的方法
      def myMax2(n:Int):Int = {
        if(n < self){
          return self //相当于谁大就返回谁
        }else{
          return n
        }
      }
      def myMin2(n:Int) = if(n < self) n else self //这两种写法都是一样的也可以简便成这样
    }
    println(12.myMax2(16)) //隐式类定义出来就可以直接调用了,不用专门去定义一个对象调用
    println(12.myMin2(15))

  }
}

class MyRichInt(val self:Int){
  // 自定义比较大小的方法
  def myMax(n:Int):Int = {
    if(n < self){
       return self //相当于谁大就返回谁
    }else{
      return n
    }
  }
  def myMin(n:Int) = if(n < self) n else self //这两种写法都是一样的也可以简便成这样
}

二、隐式参数

普通方法或者函数中的参数可以通过implicit关键字声明为隐式参数,调用该方法时,就可以传入该参数,编译器会在相应的作用域寻找符合条件的隐式值。
隐式参数说明
(1) 在同一个作用域中,相同类型的隐式值只能有一个
(2) 编译器按照隐式参数的类型去寻找对应类型的隐式值,与隐式值的名称无关。
(3) 隐式参数优先于默认参数

 //3、隐式参数
    //相同作用域下,相同类型的隐式参数只能有一个,
    implicit val names:String = "aex" //函数里定义了隐式参数调用不传参数,但是至少得告诉在哪里去找,所以在外面定义一个隐式参数
    implicit val age:Int = 18
    def sayHello(implicit name:String):Unit={
      println("hello" + name)
    }
    def sayHi(implicit name:String):Unit={
      println("hello" + name)
    }

    //有隐式参数之后,就不用传参数了。直接把括号给去掉
    sayHello //函数可以直接调用,但是里面要传个参数,要是不传参数的话就会报错

三、隐式类

在Scala2.10 后提供了隐式类,可以用implicit声明类,隐式类非常强大,同样可以扩展类的功能,在集合中隐式类会发挥重要的作用
隐式类说明
(1) 其所带的构造参数有且只能有一个
(2) 隐式类必须被定义在 “类” 或 “伴生对象” 或 “包对象” 里,即隐式类不能是顶级的

package Scala05_yichang
// implicit 隐式转换
class test02_implicit {

}
object test02_implicit{
  def main(args: Array[String]): Unit = {
    val a = new MyRichInt(12)
    println(a.myMax(15)) //做一个比较,15比12大输出的就是15


    //1、隐式函数
    implicit def convert(num:Int):MyRichInt = new MyRichInt(num)
    println(12.myMax(15)) //这个调用要放在隐式函数下面,因为这才是他的作用域

    println("===================")
    //2、隐式类
    implicit class MyRichInt2(val self:Int){ //这个隐式类必须要放在一个类或者对象里面。因为他不能是最顶级的
      // 自定义比较大小的方法
      def myMax2(n:Int):Int = {
        if(n < self){
          return self //相当于谁大就返回谁
        }else{
          return n
        }
      }
      def myMin2(n:Int) = if(n < self) n else self //这两种写法都是一样的也可以简便成这样
    }
    println(12.myMax2(16)) //隐式类定义出来就可以直接调用了,不用专门去定义一个对象调用
    println(12.myMin2(15))

  }
}

class MyRichInt(val self:Int){
  // 自定义比较大小的方法
  def myMax(n:Int):Int = {
    if(n < self){
       return self //相当于谁大就返回谁
    }else{
      return n
    }
  }
  def myMin(n:Int) = if(n < self) n else self //这两种写法都是一样的也可以简便成这样
}

四、隐式解析机制

隐式解析机制说明
(1) 首先会在当前代码作用域下查找隐式实体(隐式方法,隐式类,隐式对象)。(一般是这种情况)
(2) 如果第一条规则查找隐式实体失败,会继续在隐式参数的类型的作用域里查找。类型的作用域是指与该类型相关的全部伴生对象以及该类型所在包的包对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值