1.27
隐式转换和隐式参数
隐式转换
隐式转换指用 implicit 关键字 声明的带有 单个参数 的方法。该方法是被自动调用的,用来实现自动将某种类型的数据转换为另一种类型的数据。
示例:手动导入
通过隐式转换,让 File 类的对象具有 read 功能。
执行流程:file对象没有read方法 -> 有隐式转换 -> 将File转为RichFile对象
object ClassDemo {
class RichFile(file: File){
//定义 read 方法
def read(): String = Source.fromFile(file).mkString
}
object Implicit{
implicit def file2RichFile(file: File): RichFile = new RichFile(file)
}
def main(args: Array[String]): Unit = {
//手动导入
import Implicit.file2RichFile
val file = new File("./data/1.txt")
file.read()
}
}
自动调用隐式转换:
当对象调用类中不存在的方法或成员时
当方法参数类型与目标类型不一致时
如果在当前作用域存在隐式转换方法,会自动导入隐式转换
object ClassDemo {
class RichFile(file: File){
//定义 read 方法
def read(): String = Source.fromFile(file).mkString
}
def main(args: Array[String]): Unit = {
//自动导入
implicit def file2RichFile(file: File): RichFile = new RichFile(file)
val file = new File("./data/1.txt")
file.read()
}
}
隐式参数
隐式参数指用 implicit 关键字 修饰的变量。调用方法时可以不给定初始值,因为编译器会自动查找缺省值。
使用步骤:
在方法后添加一个参数列表,参数使用 implicit 修饰
在 object 中定义 implicit 修饰的隐式值
调用该方法,可以不传入 implicit 修饰的参数值
和隐式转换一样,可以手动导入,如果作用域内定义了隐式值可以自动导入。
定义一个show方法,实现将传入的值,使用指定前缀分隔符和后缀分隔符包装起来。
例如 show(“a”)("<<",">>") // <<a>>
object ClassDemo {
//name表示姓名,第一个String表示前缀信息,第二个String表示后缀信息
def show(name:String)(implicit delimit:(String, String)): String = delimit._1 + name +delimit._2
//定义单例对象,用来给隐式参数默认值
object Implicit{
implicit val delimit_default: (String, String) = ("<<" ,">>")
}
def main(args: Array[String]): Unit = {
//手动导入
import Implicit.delimit_default
//调用show
println(show("abc"))//<<abc>>
println(show("abc")("<-", "->"))//<-abc->
}
}
自动导入
object ClassDemo {
//name表示姓名,第一个String表示前缀信息,第二个String表示后缀信息
def show(name:String)(implicit delimit:(String, String)): String = delimit._1 + name +delimit._2
def main(args: Array[String]): Unit = {
//自动导入
implicit val delimit_default: (String, String) = ("<<" ,">>")
//调用show
println(show("abc"))//<<abc>>
println(show("abc")("<-", "->"))//<-abc->
}
}
案例:获取列表元素平均值
通过隐式转换,获取列表中所有元素的平均值。
object ClassDemo {
class RichList(list: List[Int]){
def avg(): Option[Int] = {
if(list.isEmpty)
None
else
Some(list.sum / list.size)
}
}
def main(args: Array[String]): Unit = {
//自动导入
implicit def list2RichList(list: List[Int]): RichList = new RichList(list)
//调用
val list = (1 to 10).toList
println(list.avg())//Some(5)
}
}

浙公网安备 33010602011771号