Scala中的隐式转换彻底精通

       序言:Scala隐式转换具有很强大的功能。Scala隐式转换让Scala编程语言更加富有变现力,不需要将一些显而易见的类型转换写入代码。Scala隐式转换也帮助实现不需要修改代码就可以扩展新功能。Scala隐式转换用implicit修饰符表示,可以作用在诸如类,参数和值等Scala关键字,使之分别称为隐式类,隐式参数和隐式值。

      一😊隐式转换使用条件

隐式转换是函数参数或者对象的隐式转换,隐式值必须在伴生对象中声明。

隐式转换使用的条件

   (1)传入参数类型与预期类型不匹配时,会找是否有将该参数类型转换为预期参数类型的隐式值;如果调用该函数的对象可以找到匹配的隐式值,同样会发生隐式转换。

  (2)当对象访问不存在成员时,会找该对象是否有转换成其他对象的隐式值.

 使用隐式转换的限制条件

     (1)implicit关键字只能用来修饰方法,变量(参数)和伴生对象

      (2)隐式转换的方法(变量和伴生对象)在当前范围内才有效。如果隐式转换不在当前范围内定义(比如定义在另外一个类中或包含在某个对象中),那么必须通过import语句将其导入.

二代码实操:

隐式函数
 

package org.jy.data.yh.bigdata.drools.scala.grammar
/**
  * 隐式函数
  * 隐式转换案例一:隐式转换是Scala的重难点之一
  */
object ImplicitTest {
  implicit def a2RichA(a:A) = new RichA(a)  // 定义一个名称为a2RichA的隐式方法(函数),前后两个参数必须相同,都为a
  def main(args:Array[String]):Unit = {
    val a = new A
    a.rich
  }
  //class Implicit{}  // 定不定义没关系
  class A{}  // 定义类A
  class RichA(a:A){ // 主构造方法
     def rich(): Unit ={
       println("这是一个隐式语法测试的实例")
     }
  }
}

======================================================

package org.jy.data.yh.bigdata.drools.scala.grammar

/**
  * 隐式函数的定义
  */
object FuncTest {
  implicit def int2String(i:Int)=i.toString
}
package org.jy.data.yh.bigdata.drools.scala.grammar
import org.jy.data.yh.bigdata.drools.scala.grammar.FuncTest._; // 导入隐式函数可用作用域
/**
  * 隐式函数
  *import org.jy.data.yh.bigdata.drools.scala.grammar.FuncTest._会将FuncTest对象内部的成员导入到相应的作用域内,
  * 否则无法调用隐式函数,FuncTest对象必须定义在调用类之前或者定义到不同的文件中
  */
object ImportInt2StringTest {
  //import org.jy.data.yh.bigdata.drools.scala.grammar.FuncTest._; // 导入隐式函数可用作用域
  def main(args:Array[String]) :Unit = {
    println(20.length)
  }

}

===========================================================

package org.jy.data.yh.bigdata.drools.scala.grammar

/**
  * 隐式函数定义
  * 该实例:Int类型隐式转换为String类型
  */
object Int2StringImplicit {
  implicit def int2String(a:Int) = a.toString

  def main(args:Array[String]):Unit = {
    println(13.length())  // Int类型无length方法,如果注释掉上面的隐式转换函数,则会编译报错
  }

}
package org.jy.data.yh.bigdata.drools.scala.grammar

/**
  * 隐式参数实战:该实例定义了带有 隐式参数str的函数hiScala
  * 并且定义了隐式值name,函数的隐式值会在本实例域内寻找一个对应的字符串类型的隐式值。若没有则编译报错could not find
  * implicit value for parameter str: String;
  * 若有多个则编译器会报错ambiguous implicit values,就是有歧义,找到了多个而不知道用那个
  */
object ArgumentsImplicitTest {
  def main(args: Array[String]): Unit = {
    hiScala
  }
  implicit  val name :String ="这是一个隐式参数实战的例子"
  //implicit val sex:String ="female"
  def hiScala(implicit  str:String) {
    println("str is: "+str)
  }
}

========================================================

隐式类

package org.jy.data.yh.bigdata.drools.scala.grammar

/**
  * 【隐式类】:就是对类增加Implicit限定的类,其作用主要是对类的加强
  * Calc前面的implicit,通过这个隐式类,就可以让Int数据类型具有add方法,整数类型本身没有add方法,
  * 编译器在遇到1.add(20)时不会立马报错,而检查当前的作用域有没有implicit修饰的,可以将Int作为参数的构造器,
  * 并且具有方法add的类
  *
  */
object ImplicitPraciteTest {
  def main(args:Array[String]){  // 自动推断类型main函数
    println("1.add(20): "+1.add(20))
     }
  implicit class Cal(x:Int){  // 定义隐式类,该类中有一个方法
    def add(a:Int):Int ={  // 返回值为Int类型
      a+ x
    }
  }

}

=======================================================

隐式值

package org.jy.data.yh.bigdata.drools.scala.grammar

/**
  * 隐式值:就是定义在object对象中的隐式变量
  * 该实例中定义了隐式变量name,方法hiScala有隐式参数,若在调用hiScala时没有显示参入参数,则会调用
  * 对应类型的隐式值
  * 注意:相同类型的隐式值在相同作用域范围只能有一个
  */
object VarImplicitTest {
  implicit val name :String ="lisi"
  def hiScala(implicit str:String): Unit ={
    println("str is : "+str)
  }

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

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值