您好,登錄后才能下訂單哦!
這篇文章主要講解了“Scala隱式轉(zhuǎn)換和隱式參數(shù)的作用是什么”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Scala隱式轉(zhuǎn)換和隱式參數(shù)的作用是什么”吧!
隱式轉(zhuǎn)換和隱式參數(shù)是Scala中兩個非常強大的功能,利用隱式轉(zhuǎn)換和隱式參數(shù),你可以提供優(yōu)雅的類庫,對類庫的使用者隱匿掉那些枯燥乏味的細節(jié)。
隱式的對類的方法進行增強,豐富現(xiàn)有類庫的功能
object ImplicitDemo extends App{
//定義隱式類,可以把File轉(zhuǎn)換成定義的隱式類RichFile
implicit class RichFile(from:File){
def read:String = Source.fromFile(from.getPath).mkString
}
//使用隱式類做已有類的動能的擴展
val contents = new File("src/test1.txt").read
println(contents)
}
創(chuàng)建隱式類時,只需要在對應(yīng)的類前加上implicit關(guān)鍵字。比如:
object Helpers {
implicit class IntWithTimes(x: Int) {
def times[A](f: => A): Unit = {
def loop(current: Int): Unit =
if(current > 0) {
f
loop(current - 1)
}
loop(x)
}
}
}
這個例子創(chuàng)建了一個名為IntWithTimes的隱式類。這個類包含一個int值和一個名為times的方法。要使用這個類,只需將其導入作用域內(nèi)并調(diào)用times方法。比如:
scala> import Helpers._
import Helpers._
scala> 5 times println("HI")
HI
HI
HI
HI
HI
使用隱式類時,類名必須在當前作用域內(nèi)可見且無歧義,這一要求與隱式值等其他隱式類型轉(zhuǎn)換方式類似。
只能在別的trait/類/對象內(nèi)部定義。
object Helpers {
implicit class RichInt(x: Int) // 正確!
}
implicit class RichDouble(x: Double) // 錯誤!
構(gòu)造函數(shù)只能攜帶一個非隱式參數(shù)。
implicit class RichDate(date: java.util.Date) // 正確!
implicit class Indexer[T](collecton: Seq[T], index: Int) // 錯誤!
implicit class Indexer[T](collecton: Seq[T])(implicit index: Index) // 正確!
雖然我們可以創(chuàng)建帶有多個非隱式參數(shù)的隱式類,但這些類無法用于隱式轉(zhuǎn)換。
在同一作用域內(nèi),不能有任何方法、成員或?qū)ο笈c隱式類同名。
object Bar
implicit class Bar(x: Int) // 錯誤!
val x = 5
implicit class x(y: Int) // 錯誤!
implicit case class Baz(x: Int) // 錯誤!
是指那種以implicit關(guān)鍵字聲明的帶有單個參數(shù)的函數(shù),這種函數(shù)將被自動引用,將值從一種類型轉(zhuǎn)換成另一種類型。
使用隱含轉(zhuǎn)換將變量轉(zhuǎn)換成預期的類型是編譯器最先使用 implicit 的地方。這個規(guī)則非常簡單,當編譯器看到類型X而卻需要類型Y,它就在當前作用域查找是否定義了從類型X到類型Y的隱式定義。
比如,通常情況下,雙精度實數(shù)不能直接當整數(shù)使用,因為會損失精度:
scala> val i:Int = 3.5
<console>:7: error: type mismatch;
found : Double(3.5)
required: Int
val i:Int = 3.5
^
當然你可以直接調(diào)用 3.5.toInt。
這里我們定義一個從 Double 到 Int 的隱含類型轉(zhuǎn)換的定義,然后再把 3.5 賦值給整數(shù),就不會報錯。
scala> implicit def doubleToInt(x:Double) = x toInt
doubleToInt: (x: Double)Int
scala> val i:Int = 3.5
i: Int = 3
此時編譯器看到一個浮點數(shù) 3.5,而當前賦值語句需要一個整數(shù),此時按照一般情況,編譯器會報錯,但在報錯之前,編譯器會搜尋是否定義了從 Double 到 Int 的隱含類型轉(zhuǎn)換,本例,它找到了一個 doubleToInt。 因此編譯器將把
val i:Int = 3.5
轉(zhuǎn)換成
val i:Int = doubleToInt(3.5)
這就是一個隱含轉(zhuǎn)換的例子,但是從浮點數(shù)自動轉(zhuǎn)換成整數(shù)并不是一個好的例子,因為會損失精度。 Scala 在需要時會自動把整數(shù)轉(zhuǎn)換成雙精度實數(shù),這是因為在 Scala.Predef 對象中定義了一個
implicit def int2double(x:Int) :Double = x.toDouble
而 Scala.Predef 是自動引入到當前作用域的,因此編譯器在需要時會自動把整數(shù)轉(zhuǎn)換成 Double 類型。
object Test{
trait Adder[T] {
def add(x:T,y:T):T
}
implicit val a = new Adder[Int] {
override def add(x: Int, y: Int): Int = x+y
}
def addTest(x:Int,y:Int)(implicit adder: Adder[Int]) = {
adder.add(x,y)
}
addTest(1,2) // 正確, = 3
addTest(1,2)(a) // 正確, = 3
addTest(1,2)(new Adder[Int] {
override def add(x: Int, y: Int): Int = x-y
}) // 同樣正確, = -1
}
感謝各位的閱讀,以上就是“Scala隱式轉(zhuǎn)換和隱式參數(shù)的作用是什么”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對Scala隱式轉(zhuǎn)換和隱式參數(shù)的作用是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。