本篇作為scala快速入門系列的第三十七篇部落格,為大家帶來的是關于隐式轉換和隐式參數的内容。

隐式轉換
Scala提供的隐式轉換和隐式參數功能,是非常有特色的功能。是Java等程式設計語言所沒有的功能。它可以允許你手動指定,将某種類型的對象轉換成其他類型的對象或者是給一個類增加方法。通過這些功能,可以實作非常強大、特殊的功能。
Scala的隐式轉換,其實最核心的就是定義隐式轉換方法,即implicit conversion function。定義的隐式轉換方法,隻要在編寫的程式内引入,就會被Scala自動使用。Scala會根據隐式轉換方法的簽名,在程式中使用到隐式轉換方法接收的參數類型定義的對象時,會自動将其傳入隐式轉換方法,轉換為另外一種類型的對象并傳回。這就是“隐式轉換”。其中所有的隐式值和隐式方法必須放到object中。
然而使用Scala的隐式轉換是有一定的限制的,總結如下:
- implicit關鍵字隻能用來修飾方法、變量(參數)。
- 隐式轉換的方法在目前範圍内才有效。如果隐式轉換不在目前範圍内定義(比如定義在另一個類中或包含在某個對象中),那麼必須通過
語句将其導。import
隐式參數
所謂的隐式參數,指的是在函數或者方法中,定義一個用
implicit
修飾的參數,此時Scala會嘗試找到一個指定類型的,用
implicit
修飾的參數,即隐式值,并注入參數。
Scala會在兩個範圍内查找:
- 目前作用域内可見的val或var定義的隐式變量;
- 一種是隐式參數類型的伴生對象内的隐式值;
隐式轉換方法作用域與導入
(1)Scala預設會使用兩種隐式轉換,一種是源類型或者目标類型的伴生對象内的隐式轉換方法;一種是目前程式作用域内的可以用唯一辨別符表示的隐式轉換方法。
(2)如果隐式轉換方法不在上述兩種情況下的話,那麼就必須手動使用import文法引入某個包下的隐式轉換方法,比如
import test._
。通常建議,僅僅在需要進行隐式轉換的地方,用import導入隐式轉換方法,這樣可以縮小隐式轉換方法的作用域,避免不需要的隐式轉換。
隐式轉換的時機
(1)當對象調用類中不存在的方法或成員時,編譯器會自動将對象進行隐式轉換.
(2)當方法中的參數的類型與目标類型不一緻時
隐式轉換和隐式參數案例
① 隐式轉換案例一(讓File類具備RichFile類中的read方法)
package cn.itcast.implic_demo
import java.io.File
import scala.io.Source
object MyPredef{
//定義隐式轉換方法
implicit def file2RichFile(file: File)=new RichFile(file)
}
class RichFile(val f:File) {
def read()=Source.fromFile(f).mkString
}
object RichFile{
def main(args: Array[String]) {
val f=new File("E://words.txt")
//使用import導入隐式轉換方法
import MyPredef._
//通過隐式轉換,讓File類具備了RichFile類中的方法
val content=f.read()
println(content)
}
}
複制
② 隐式轉換案例二(超人變身)
package cn.itcast.implic_demo
class Man(val name:String)
class SuperMan(val name: String) {
def heat=print("超人打怪獸")
}
object SuperMan{
//隐式轉換方法
implicit def man2SuperMan(man:Man)=new SuperMan(man.name)
def main(args: Array[String]) {
val hero=new Man("hero")
//Man具備了SuperMan的方法
hero.heat
}
}
複制
③ 隐式轉換案例三(一個類隐式轉換成具有相同方法的多個類)
package cn.itcast.implic_demo
class A(c:C) {
def readBook(): Unit ={
println("A說:好書好書...")
}
}
class B(c:C){
def readBook(): Unit ={
println("B說:看不懂...")
}
def writeBook(): Unit ={
println("B說:不會寫...")
}
}
class C
object AB{
//建立一個類的2個類的隐式轉換
implicit def C2A(c:C)=new A(c)
implicit def C2B(c:C)=new B(c)
}
object B{
def main(args: Array[String]) {
//導包
//1. import AB._ 會将AB類下的所有隐式轉換導進來
//2. import AB._C2A 隻導入C類到A類的的隐式轉換方法
//3. import AB._C2B 隻導入C類到B類的的隐式轉換方法
import AB._
val c=new C
//由于A類與B類中都有readBook(),隻能導入其中一個,否則調用共同方法時代碼報錯
//c.readBook()
//C類可以執行B類中的writeBook()
c.writeBook()
}
}
複制
④ 隐式參數案例四(員工領取薪水)
package cn.itcast.implic_demo
object Company{
//在object中定義隐式值 注意:同一類型的隐式值隻允許出現一次,否則會報錯
implicit val aaa="zhangsan"
implicit val bbb=10000.00
}
class Boss {
//注意參數比對的類型 它需要的是String類型的隐式值
def callName()(implicit name:String):String={
name+" is coming !"
}
//定義一個用implicit修飾的參數
//注意參數比對的類型 它需要的是Double類型的隐式值
def getMoney()(implicit money:Double):String={
" 當月薪水:"+money
}
}
object Boss extends App{
//使用import導入定義好的隐式值,注意:必須先加載否則會報錯
import Company._
val boss =new Boss
println(boss.callName()+boss.getMoney())
}
複制
本期的内容分享就到這裡了,喜歡的小夥伴們記得點個贊,持續關注喲~下期為大家介紹的是scala的Actor并發程式設計,敬請期待٩(๑>◡<๑)۶