1 什么情况下会发生隐式转化
总的来说就是定义了,用到了。详细情况用下面几个例子来演示。
1.1 第一种情况
package com.cma.implicits
import java.io.File
object ImplicitsWhen {
def main(args: Array[String]): Unit = {
//定义并导入两个隐式转化函数,如果需要,扩展的方法可以直接被file对象使用
implicit def file2FirstRichFile(file: File) = new FirstRichFile(file)
implicit def file2SecondRichFile(file: File) = new SecondRichFile(file)
val file = new File("E:\\hosts.txt")
//调用第一个隐式转化
println(file.readAllLine)
//调用第二个隐式转化,然后再调用第一个隐式转化
println(file.showAllLine.readAllLine)
}
class FirstRichFile(file: File) {
println("进入FirstRichFile ... ")
def readAllLine = scala.io.Source.fromFile(file).mkString
}
class SecondRichFile(file: File) {
println("进入SecondRichFile ...")
def showAllLine = {
println(scala.io.Source.fromFile(file).mkString)
//SecondRichFile object 隐式转化后的对象
//this
//File object,隐式转化之前的对象。目的是进行链式操作
file
}
}
}
1.2 第二种情况
package com.cma.implicits
object ImplicitWhenSecond {
def main(args: Array[String]): Unit = {
/*
* sqrt求平方根这个方法的输入是Double类型,
* 下面的代码会把整形4先转化为Double
*/
val sqrt = scala.math.sqrt(4)
println(sqrt)
}
}
1.3 第三种情况
package com.cma.implicits
object DefaultValue {
def main(args: Array[String]): Unit = {
implicit val from : String = "unknown"
val content : String = "hello,baby!"
readLetter(content)
}
def readLetter(content : String)(implicit from : String) = {
println(content)
println(from)
}
}
package com.cma.implicits
object ClassAsDefaultValue {
def main(args: Array[String]): Unit = {
val user = User(1 , "flankwang")
implicit val livingCost = new LivingCost(850 , 300 , 1500)
implicit val xxx = "QQ"
showLivingCost(user)
}
def showLivingCost(user : User)(implicit livingCost : LivingCost , xxx : String) = {
println("用户 : " + user.name + user.id + "月预算清单 : ")
println("rent :" + livingCost.rent + ", traffic : " + livingCost.traffic +",food : " +livingCost.food)
println(xxx)
}
case class User(id : Int , name : String)
case class LivingCost(rent : Int , traffic : Int , food : Int)
}
1.4 第四种情况(context bond使用)
package com.cma.implicits
object ContextBound {
def main(args: Array[String]): Unit = {
println(smaller(1)(2))
println(smaller(new User(1))(new User(2)))
}
/**
* first : 第一个参数
* second : 第二个参数
* order : 一个隐式转化函数,输入是T,输出是Ordered[T]
* 这也是ContextBound的概念。
* first second 需要比较大小,但是二者中都没有"<"这样的操作。怎么办呢?,T是没有,
* 但是Ordered[T]中有,只要我们把T =>Ordered[T]不就可以了吗。
* 对,我们这里就是这样干的。
* 还有一点很重要 Ordered[T]是一个trait,集成了JAVA的Comparable,重写compareTo
* (def compareTo(that: A): Int = compare(that)),这里compare是一个抽象方法
* 。< > 等等方法的定义中使用到了compare.这就要求我们的T实现compare抽象方法
*/
def smaller[T](first : T)(second : T)(implicit order : T => Ordered[T]) = {
if(first < second) first else second
}
/**
* id : 用户ID编号
* val id : Int,这里之所以用val ,是为了让that也可以访问id
*/
class User(val id : Int ) extends Ordered[User]{
def compare(that: User): Int = {
if (this.id < that.id) 1 else if(this.id == that.id) 0 else -1
}
override def toString() = {
"userId : "+ id
}
}
}