- 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中的隐式转换可以将一个对象根据隐式转换转成另一种类型,方便使用
- 以后开发中我们只需要导入别人写好的隐式转换即可
- 如:
import spark.implicits._
import org.apache.flink.api.scala._
package cn.hanjiaxiaozhi.implicitdemo
import java.io.File
import scala.io.Source
class MyFile(val file:File){
def read() = {
Source.fromFile(file).mkString
}
}
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")
import File2MyFile.transform
val str: String = file.read()
println(str)
}
}
隐式参数
- Scala中的隐式参数可以通过导入参数的形式将参数自动/隐式的传递给带有隐式参数的方法
package cn.hanjiaxiaozhi.implicitdemo
object ImplicitParam {
implicit val t1 = ("<<",">>")
implicit val t2 = ("[","]")
}
object ImplicitDemo2 {
def getName(name: String)(implicit t:(String,String)): String = {
t._1 + name + t._2
}
def main(args: Array[String]): Unit = {
import ImplicitParam.t2
val name: String = getName("Scala从入门到精通")
println(name)
}
}