Scala物件導向程式設計 隱式轉換

2021-10-08 13:08:37 字數 3608 閱讀 9100

隱式轉換就是自動型別轉換。 如 var dbl:double = 12 int 自動轉換double, 但是 val num:int =3.5 確會報錯。我們可以自己通過定義隱式轉換來實現 double自動轉換int

隱式轉換函式是以implicit 關鍵字宣告的帶有單個引數的函式,這種函式會自動應用將值從一種型別轉換為另一種型別

注意事項:

1)隱式轉換的函式名可以是任意的,飲食轉換與函式名無關,只和函式簽名(引數型別和返回值型別)有關

2)隱式函式可以有多個,但是要保證在當前環境下只有乙個隱式函式可以被識別,如果有多個函式都可以使用 那編譯器就不知道要用哪個了

示例

def test: unit =

implicit def f2

(d:float)

: int =

// implicit def f3(d:float): int =

val num:int =

3.5//定義隱式轉換函式後 這種寫法不再報錯

var num2:int =

2.1f

}

反編譯底層實現

public

final

class

class09$

public

void

test()

public

void

main

(string[

] args)

private

static

final

int f1$1

(double d)

private

static

final

int f2$1

(float d)

private class09$(

)}

隱式轉換可以豐富類功能

示例

class

mysql

}classdb}

def test: unit =

var mysql =

newmysql

mysql.

insert()

//因為有了上述隱式轉換函式 mysql可以執行 db類中的操作

//編譯器在編譯時會呼叫隱式函式 adddelete 並得到乙個db物件 然後執行 db物件的 delete方法

mysql.

delete()

}

反編譯

public

void

test()

隱式值也叫做隱式變數,將某個形參變數標記為implicit後,如果呼叫方法時為傳入引數,那麼編譯器會

搜尋作用域內對應的隱式值作為預設引數

注意事項:

1)在程式當中 呼叫乙個方法時,同時有隱式值、預設值、和傳入值 編譯器的採用的優先順序為 傳值》隱式值》預設值

2)隱式值在匹配時,不能有二義性

3)如果方法呼叫時 沒有傳值 同時也沒有 隱式值和預設值 那麼 程式會報錯

示例:

def test: unit =

def hello2

(implicit param:string=

"預設引數值"

): unit =

hello //hi~scala 法引數只有隱式值 因此 輸出 隱式值

hello2//hi~scala 法引數隱式值和預設值同時存在 使用隱式值

hello

("傳入值"

)//hi~傳入值 方法引數有傳入值時 使用傳入值

//實時上 使用隱式值 發生在編譯階段 而使用 預設值 發生在 執行階段,所以 隱式值得優先順序比預設值高

編譯後的test方法如下:
public

void

test()

}

scala2.10之後提供了隱式類,可以使用implicit宣告類,隱式類非常強大,同樣可以擴充套件類的功能

比之前使用隱式轉換豐富類功能更加方便,在計畫中隱式類會發揮很大的作用

隱式類有以下特點

1)它構造器的引數有且只有乙個

2)隱式類必須定義在類、伴生物件或包物件中,不能直接定義在包下(因為這樣不明確作用範圍)

3)隱式類不能是case class

4)作用域內不能有與之相同名稱的識別符號

示例:

class

mysql

} def test: unit =

} var mysql=

newmysql

mysql.

sayhi()

mysql.

showinfo()

//可以呼叫 db 類中的方法

}

反編譯 db類如下 編譯器生成的db類 擁有乙個mysql型別的屬性

public

class

class09$db$1

public

void

showinfo()

}

test 方法反編譯如下,在呼叫db的方法時 根據mysql例項建立乙個 db例項 然後執行方法

public

final

class

class09$

public

void

test()

public

void

main

(string[

] args)

private

static

final class09.db.

1 db$2

(class09.mysql m)

private class09$(

)}

1)當方法中的引數型別與目標型別不一致時,或者為變數賦值本身型別和目標型別不一直是 val a:int=3.4

2) 當物件呼叫本類中不存在的方法或成員時,編譯器會自動將物件進行隱式轉換

編譯器是如何查詢到缺失資訊並完成對應的隱式轉換的?

1)首先編譯器會在當前**作用域下查詢隱式實體(隱式方法、隱式類、隱式物件)

大部分都是這種情況

2)如果第一條規則查詢失敗,編譯器會繼續在隱式引數型別的作用域李查詢。

型別的作用域指與該型別相關聯的全部伴生模組。乙個隱式實體的型別t查詢範圍如下

(這種情況範圍廣且複雜,實際開發中盡量避免使用)

a)如果t被定義為 t with a with b with c 那麼 abc 都是t 的部分,在t的隱式解析過程中他們的伴生物件都會被搜尋

b)如果t是引數化型別,那麼型別引數和與型別引數相關聯的部分都算作t的部分,如

list[string]的隱式搜做會搜尋list 和 string 的的伴生物件

c)如果t是乙個單例型別, p.t,即t屬於某個物件p,那麼這個p物件也會被搜尋

d)如果t是個型別注入 s#t,那麼s和t 都會被搜尋

隱式轉換時需要遵循兩個基本前提

1)不能有二義性

2)隱式操作不能巢狀使用

scala 隱式轉換

defdisplay input string unit println input implicit deftypeconvertor input int string input.tostring implicit deftypeconvertor input boolean string if...

scala 隱式轉換

隱式轉換就是 當scala編譯器進行型別匹配時,如果找不到合適的候選,那麼隱式轉化提供了另外一種途徑來告訴編譯器如何將當前的型別轉換成預期型別。使用方式 將方法或變數標記為implicit 將方法的引數列表標記為implicit 將類標記為implicit 宣告乙個帶有implicit修飾過引數的方...

scala隱式轉換

目錄 隱式轉換的概念 隱式轉換的使用 隱式轉換做引數型別轉換 隱式轉換增強現有型別 隱式引數 利用隱式引數進行隱式轉換 再議context bounds 隱式轉換函式 implicit conversion function 是以implicit關鍵字宣告的帶有單個引數的函式,這樣的函式將被自動應用...