scala--隐式转换和隐式参数-★★★

隐式转换和隐式参数

  • java中没有隐式转换和隐式参数
  • Java中如果要实现得使用动态代理/AOP等技术
  • 概述
    • Scala提供的隐式转换和隐式参数功能非常具有特色,也是Java等编程语言所没有的功能。
    • 可以将某种类型的对象转换成指定类型或者是给一个类型增加新的方法(可以不修改原来的代码而为代码增加新功能)
    • 后面在学习Akka、Spark、Flink等都会看到隐式转换和隐式参数的身影,可以实现非常强大且特殊的功能。
  • 隐式转换
    • 所谓隐式转换,是指以implicit关键字声明的带有单个参数的方法。
    • 定义的隐式转换方法,只要在编写的程序内引入(import),就会被Scala自动调用。
    • Scala会根据隐式转换方法的签名,在程序中使用到隐式转换方法接收的参数类型定义的对象时,会自动将其传入隐式转换方法,转换为另外一种类型的对象并返回。
  • 隐式参数
    • 所谓的隐式参数,指的是在函数或者方法中,定义一个用implicit修饰的参数,此时编译器会尝试找到一个指定类型的,用implicit修饰的隐式值并设置给该参数。
    • Scala会在两个范围内查找:当前作用域内可见的val或var定义的隐式变量、隐式参数类型的伴生对象内的隐式值
  • 隐式转换的时机
    • 当方法中的参数的类型与目标类型不一致时
    • 当对象调用类中不存在的方法或成员时,编译器会自动将对象进行隐式转换
  • 隐式转换查找与导入
    • (1)Scala默认会使用两种隐式转换,
      • 一种是源类型,或者目标类型的伴生对象内的隐式转换函数或隐式值;
      • 一种是当前程序作用域内的可以用唯一标识符表示的隐式转换方法或隐式值。
    • (2)如果不在上述两种情况下的话,
      • 那么就必须手动使用import语法引入某个包下的隐式转换,比如import test._
      • 通常建议:仅仅在需要进行隐式转换的地方,用import导入隐式转换,这样可以缩小隐式转换的作用域,避免不需要的隐式转换
  • 注意
    • 1.其中所有的隐式值和隐式方法必须放到object中。
    • 2.implicit关键字只能用来修饰方法、变量(参数)和伴随对象。
    • 3.Scala程序会自动导入以下包:
import java.lang._

import scala._

import Predef._

隐式转换

  • Scala中的隐式转换可以将一个对象根据隐式转换转成另一种类型,方便使用
  • 以后开发中我们只需要导入别人写好的隐式转换即可
  • 如:
//spark代码中经常要导入的 
import spark.implicits._ 
//flink代码中经常要导入的
import org.apache.flink.api.scala._
  • 自定义的隐式转换和使用案例
package cn.hanjiaxiaozhi.implicitdemo
​
import java.io.File
​
import scala.io.Source
​
/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 16:28
 * Desc 演示Scala中的隐式转换
 */class MyFile(val file:File){
    
    
  //在RichFile中提供一个read方法可以直接读取file中的文件内容并返回字符串
  def read() = {
    
    
    Source.fromFile(file).mkString
  }
}//定义一个object其中提供一个隐式转换方法,可以将File转为MyFile
object File2MyFile{
    
    
  implicit def transform(file:File):MyFile={
    
    
    new MyFile(file)
  }
}object ImplicitDemo1 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    val file = new File("D:\\scala\\data\\1.txt")
    //file.read()//调用不了,因为Java中自带的File中没有read方法
    //现在如果想要让file.read()不抱错,可以执行,那么可以使用Scala中的隐式转换技术
    //将file对象转换为MyFile类型,那么不就可以使用read方法了么!
    //导入上面的隐式转换方法,将file对象转换为MyFile类型
    import File2MyFile.transform//我们以后写的就是这一句,导入别人写好的隐式转换
    //这句类似于导包的语句其实就是导入上面定义好的隐式转换,在编译时期,由编译器自动将file根据隐式转换方法转为MyFile
    val str: String = file.read()
    println(str)
  }
}

隐式参数

  • Scala中的隐式参数可以通过导入参数的形式将参数自动/隐式的传递给带有隐式参数的方法
package cn.hanjiaxiaozhi.implicitdemo
​
/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 16:28
 * Desc 演示Scala中的隐式参数
 */object ImplicitParam {
    
    
  implicit val t1 = ("<<",">>")
  implicit val t2 = ("[","]")
}
​
​
object ImplicitDemo2 {
    
    
  //需求:调用getName方法返回书名并带上书名号
  def getName(name: String)(implicit t:(String,String)): String = {
    
    
    //如果是在这样的话,书名号就写死了,我们希望可以根据不同的参数,进行不同的拼接
    //但是提供参数让调用者传递,调用的时候又很麻烦
    //所以可以使用隐式参数
    t._1 + name + t._2
  }def main(args: Array[String]): Unit = {
    
    
    //这里调用getName的时候传递name即可
    //但是还需要指定一个隐式参数,也就是导包即可
    //import ImplicitParam.t1
    import ImplicitParam.t2
    val name: String = getName("Scala从入门到精通")
    println(name)
  }
}

猜你喜欢

转载自blog.csdn.net/qq_46893497/article/details/114044024