Scala 基礎11 隱式轉換和隱式值

2021-10-05 16:27:58 字數 4056 閱讀 9180

1、隱式函式

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

object scala01 

}

使用隱式函式可以優雅的解決資料型別轉換

implicit def f1

(d: double)

: int =

//double 是輸入型別, int 是轉換後的型別

編譯後:

其實就是強制型別轉換

public

final

class

scala01$

public

void

main

(string[

] args)

public

intf1

(double d)

private scala01$(

)}

2、注意事項

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

隱式函式可以有多個(即:隱式函式列表),但是需要保證在當前環境下,只有乙個隱式函式能被識別

//在當前環境中,不能存在滿足條件的多個隱式函式

implicit def a

(d: double)

= d.toint

implicit def b

(d: double)

= d.toint

val i1: int =

3.5//(x)在轉換時,識別出有兩個方法可以被使用,就不確定呼叫哪乙個,所以出錯

println

(i1)

3、隱式轉換能豐富類庫功能

如果需要為乙個類增加乙個方法,可以通過隱式轉換來實現。(動態增加功能)比如想為mysql類增加乙個delete方法

分析:

在當前程式中,如果想要給mysql類增加功能是非常簡單的,但是在實際專案中,如果想要增加新的功能就會需要改變源**,這是很難接受的。而且違背了軟體開發的ocp開發原則 (閉合原則 open close priceple)

在這種情況下,可以通過隱式轉換函式給類動態新增功能

object myimplicit 

val mysql =

newmysql

mysql.

insert()

mysql.

delete()

}}class

mysql

}class

db}

insert

delete

隱式值也叫隱式變數,將某個形參變數標記為implicit,所以編譯器會在方法省略隱式引數的情況下去搜尋作用域內的隱式值作為預設引數

預設值只是對應乙個函式

隱式值對應多個函式

練習1
object implicitvaldemo 

//使用隱式值不要帶()

hello //底層 hello$1(str1);

}}

自動給隱式引數name賦值

jack~ hello
練習2
def main

(args: array[string]

): unit =

//呼叫hello

hello

}

報錯:

同時匹配到兩個隱式值name和name1,無法確定具體哪個

error:(18

,5) ambiguous implicit values:

both value name1 of type string

and value name of type string

match expected type string

hello

練習3
def main

(args: array[string]

): unit =

//呼叫hello

hello

}

當同時有implicit 值和預設值,implicit 優先順序高

hello scala
練習4
def main

(args: array[string]

): unit =

//呼叫hello

hello // hello jack

}

當乙個隱式引數匹配不到隱式值,仍然會使用預設值

hello jack
練習5
def hello

(implicit content: string )

: unit =

//呼叫hello

hello

當沒有隱式值,沒有預設值,又沒有傳值,就會報錯

小結:

當在程式中,同時有 隱式值,預設值,傳值

編譯器的優先順序為 傳值 > 隱式值 > 預設值

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

如果三個 (隱式值,預設值,傳值) 乙個都沒有,就會報錯

在scala2.10後提供了隱式類,可以使用implicit宣告類,隱式類的非常強大,同樣可以擴充套件類的功能,比前面使用隱式轉換豐富類庫功能更加的方便,在集合中隱式類會發揮重要的作用。

特點其所帶的構造引數有且只能有乙個

隱式類必須被定義在「類」或「伴生物件」或「包物件」裡,即隱式類不能是 頂級的(top-level objects)隱式類不能是case class

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

object implicitclassdemo 

}//class db1 {} 此處不可定義類db1 重名

//建立乙個mysql1例項

val mysql =

newmysql1

mysql.

sayok()

mysql.

addsuffix()

//研究 如何關聯到 db1$1(mysql).addsuffix();

implicit def f1

(d:double)

: int =

def test1

(n1:int)

: unit =

test1

(10.1)}

}class

db1//此處可以定義類db1

class

mysql1

}

當方法中的引數的型別與目標型別不一致時

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

即編譯器是如何查詢到缺失資訊的,解析具有以下兩種規則:

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

(一般是這種情況)

如果第一條規則查詢隱式實體失敗,會繼續在隱式引數的型別的作用域裡查詢。型別的作用域是指與該型別相關聯的全部伴生模組,乙個隱式實體的型別t它的查詢範圍如下:

(第二種情況範圍廣且複雜在使用時,應當盡量避免出現)

在進行隱式轉換時,需要遵守兩個基本的前提:

不能存在二義性

隱式操作不能巢狀使用

def main

(args: array[string]

): unit =

val num1: int =

1.1}

Scala 隱式轉換和隱式引數

紙上得來終覺淺,絕知此事要躬行!隱式函式基本介紹 隱式轉換函式是以implicit關鍵字宣告的帶有單個引數的函式。這種函式將會自動應用,將值從一種型別轉換為另一種型別 隱式函式快速入門 使用隱式函式可以優雅的解決資料型別轉換,案例入門.implicit def f1 d double int dou...

Scala的隱式引數和隱式轉換

隱式 implicit 是scala中最重要的內容同時也是最難懂的概念。在scala中隱式的概念主要包括三個方面的內容 1隱式引數 2隱式轉換 3隱式呼叫 首先隱式implicit 是什麼意思?在scala中implicit是在編譯器需要修復型別匹配時,可以用來自動插入的定義。比如舉個例子,我要把2...

scala 隱式轉換

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