scala隐式转换应用

隐式转换是scala的一个难点,下面几个案例用来帮助理解它。

案例一:想要增强某一个系统类的方法,比如为scala.reflect.io.File 添加一个read方法,实现类似下面的写法,

1
2
val file = File(filePath)
print(file.read())

具体实现

1
2
3
4
5
6
7
8
9
10
11

class RichFile(file : File) {
def read() : String = {
Source.formFile(file.path).mkString
}
}

// 隐式转换只能写在伴生对象中
object RichFile{
implicit def file2RichFile(file : File) : RichFile = new RichFile(file)
}

在另一个类的main方法中调用

1
2
3
4
5
def main(args : Array[String]) : Unit = {
import RichFile._
println(File("/home/zyh/1.txt").read())

}

案例二: 比较Person中年龄的大小 ,这里不局限Person,可以用泛型T

编写自定义的Person类

1
2
3
4

class Person (var name:String , var age : Int){

}

我们定义一个比较的方法,如果我们写成这样,编译器是会报错的,因为编译器不知道T是什么,所有在使用>的时候就会报错

1
2

def compare[T](a:T,b:T) = if(a>b) a else b

我们要想下面这样去写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
object ComparePerson{
// #1 比较大小
def compare[T] (a:T,b:T) (implicit order : T => Ordered[T])= if(a>b) a else b

// #2 只定义#1.是不能比较的,因为a,b 系统不知道是什么类型,所以 > 不能使用,这边解决的方法是利用隐式转换告诉系统
implicit val person2Ordered = (person : Person) => new Ordered[Person] {
override def compare(that : Person) = {
that.age - person.age
}
}
// #3 还可以用下面的代码替换2,任选其一
implicit def person2Ordered(person : Person) = new Ordered[Person]{
override def compare.....
}

}

在主程序中调用ComparePerson.compare(p1,p2)即可,使用之前一定要引入隐式转换的方法,import ComparePerson._