好程式設計師大資料教程Scala系列之隱式轉換和隱式引數
好程式設計師大資料教程Scala系列之隱式轉換和隱式引數
5.1. 概念
隱式轉換和隱式引數是Scala中兩個非常強大的功能,利用隱式轉換和隱式引數,你可以提供優雅的類庫,對類庫的使用者隱匿掉那些枯燥乏味的細節。
5.2. 作用
隱式的對類的方法進行增強,豐富現有類庫的功能
object ImplicitDemo
extends App{
//
定義隱式類,可以把
File
轉換成定義的隱式類
RichFile
implicit
class RichFile(from:File){
def read:String = Source.fromFile(from.getPath).mkString
}
//
使用隱式類做已有類的動能的擴充套件
val contents =
new File("src/test1.txt").read
println(contents)
}
5.5. 隱式類
建立隱式類時,只需要在對應的類前加上implicit關鍵字。比如:
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)
}
}
}
這個例子建立了一個名為IntWithTimes的隱式類。這個類包含一個int值和一個名為times的方法。要使用這個類,只需將其匯入作用域內並呼叫times方法。比如:
scala>
import Helpers._
import Helpers._
scala> 5 times println("HI")
HI
HI
HI
HI
HI
使用隱式類時,類名必須在當前作用域內可見且無歧義,這一要求與隱式值等其他隱式型別轉換方式類似。
只能在別的trait/類/物件內部定義。
object Helpers {
implicit
class RichInt(x: Int)
//
正確!
}
implicit
class RichDouble(x: Double)
//
錯誤!
建構函式只能攜帶一個非隱式引數。
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)
//
正確!
雖然我們可以建立帶有多個非隱式引數的隱式類,但這些類無法用於隱式轉換。
在同一作用域內,不能有任何方法、成員或物件與隱式類同名。
object Bar
implicit
class Bar(x: Int)
//
錯誤!
val x = 5
implicit
class x(y: Int)
//
錯誤!
implicit
case
class Baz(x: Int)
//
錯誤!
5.6. 隱式轉換函式
是指那種以implicit關鍵字宣告的帶有單個引數的函式,這種函式將被自動引用,將值從一種型別轉換成另一種型別。
使用隱含轉換將變數轉換成預期的型別是編譯器最先使用 implicit 的地方。這個規則非常簡單,當編譯器看到型別X而卻需要型別Y,它就在當前作用域查詢是否定義了從型別X到型別Y的隱式定義。
比如,通常情況下,雙精度實數不能直接當整數使用,因為會損失精度:
scala>
val i:Int = 3.5
<console>:7: error:
type mismatch;
found : Double(3.5)
required: Int
val i:Int = 3.5
^
當然你可以直接呼叫 3.5.toInt。
這裡我們定義一個從 Double 到 Int 的隱含型別轉換的定義,然後再把 3.5 賦值給整數,就不會報錯。
scala>
implicit
def doubleToInt(x:Double) = x toInt
doubleToInt: (x: Double)Int
scala>
val i:Int = 3.5
i: Int = 3
此時編譯器看到一個浮點數 3.5,而當前賦值語句需要一個整數,此時按照一般情況,編譯器會報錯,但在報錯之前,編譯器會搜尋是否定義了從 Double 到 Int 的隱含型別轉換,本例,它找到了一個 doubleToInt。 因此編譯器將把
val i:Int = 3.5
轉換成
val i:Int = doubleToInt(3.5)
這就是一個隱含轉換的例子,但是從浮點數自動轉換成整數並不是一個好的例子,因為會損失精度。 Scala 在需要時會自動把整數轉換成雙精度實數,這是因為在 Scala.Predef 物件中定義了一個
implicit def int2double(x:Int) :Double = x.toDouble
而 Scala.Predef 是自動引入到當前作用域的,因此編譯器在需要時會自動把整數轉換成 Double 型別。
5.7. 隱式引數
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
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2660150/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師大資料教程Scala系列之高階函式程式設計師大資料函式
- 好程式設計師大資料教程Scala系列之類程式設計師大資料
- 好程式設計師大資料教程分享Scala系列之Option_偏函式_String程式設計師大資料函式
- 好程式設計師大資料教程Scala系列之繼承程式設計師大資料繼承
- Scala Essentials: 隱式轉換
- 好程式設計師大資料教程分享Scala系列之檔案以及正規表示式程式設計師大資料
- 好程式設計師大資料教程分享Scala系列之閉包程式設計師大資料
- scala簡明教程:偏函式、高階函式、Future非同步程式設計、隱式轉換函式非同步程式設計
- 好程式設計師大資料學習路線分享Scala系列之集合操作函式程式設計師大資料函式
- 雜記四:scala 柯理化和隱式轉換
- 好程式設計師大資料教程Scala系列之方法的巢狀和方法多型程式設計師大資料巢狀多型
- 好程式設計師大資料分享Scala系列之柯里化程式設計師大資料
- Java資料型別的顯式轉換和隱式轉換Java資料型別
- js顯式轉換和隱式轉換JS
- Cris 的 Scala 筆記整理(十):隱式轉換筆記
- 好程式設計師大資料學習路線分享Scala系列之物件程式設計師大資料物件
- JavaScript 隱式資料型別轉換JavaScript資料型別
- oracle資料隱式轉換規則Oracle
- 好程式設計師大資料培訓分享spark之Scala程式設計師大資料Spark
- 好程式設計師大資料學習路線分享Scala系列之抽象類程式設計師大資料抽象
- 好程式設計師大資料學習路線分享Scala系列之陣列程式設計師大資料陣列
- 好程式設計師大資料學習路線分享Scala系列之泛型程式設計師大資料泛型
- MySQL索引失效之隱式轉換MySql索引
- java隱式轉換Java
- javascript 隱式轉換JavaScript
- sql隱式轉換SQL
- 好程式設計師大資料學習路線分享Scala系列之對映Map程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之基礎篇程式設計師大資料
- [20191106]隱式轉換.txt
- 好程式設計師大資料學習路線分享spark之Scala程式設計師大資料Spark
- 前端面試官必問系列之隱式型別轉換前端面試型別
- JavaScript隱式型別轉換JavaScript型別
- 【C++】禁止隱式轉換C++
- mysql隱式轉換問題MySql
- 資料型別隱式轉換導致的阻塞資料型別
- 好程式設計師Python教程系列遞迴函式與匿名函式呼叫程式設計師Python遞迴函式
- Solidity語言學習筆記————11、隱式轉換和顯式轉換Solid筆記
- 好程式設計師大資料培訓分享之《MySQL資料庫》常用函式整理程式設計師大資料MySql資料庫函式