1、隱式轉(zhuǎn)換介紹
object Scala01_implicit {
def main(args: Array[String]): Unit = {
//隱式轉(zhuǎn)換(自動(dòng)轉(zhuǎn)換)
//scala默認(rèn)情況下支持?jǐn)?shù)值類型的自動(dòng)轉(zhuǎn)換
//Byte->Short->Int->Long
//scala默認(rèn)情況下支持多態(tài)的自動(dòng)類型轉(zhuǎn)換
//child->parent->trait(interface)
//scala也支持自定義隱式轉(zhuǎn)換
//將兩個(gè)無(wú)關(guān)的類型通過(guò)編程手段讓他們可以自動(dòng)轉(zhuǎn)換
implicit def transform(d:Double): Int ={
d.toInt
}
val i : Int = 5.0
println(i)//5
}
}
- 隱式轉(zhuǎn)換(自動(dòng)轉(zhuǎn)換)
- scala默認(rèn)情況下支持?jǐn)?shù)值類型的自動(dòng)轉(zhuǎn)換
Byte->Short->Int->Long- scala默認(rèn)情況下支持多態(tài)的自動(dòng)類型轉(zhuǎn)換
*child->parent->trait(interface)- scala也支持自定義隱式轉(zhuǎn)換
將兩個(gè)無(wú)關(guān)的類型通過(guò)編程手段讓他們可以自動(dòng)轉(zhuǎn)換
2猜嘱、隱式轉(zhuǎn)換增強(qiáng)功能(在不改變?cè)写a的基礎(chǔ)上店读,增強(qiáng)功能)
object Scala01_implicit {
def main(args: Array[String]): Unit = {
implicit def transform(myslq:Mysql): Operater ={
new Operater()
}
val mysql: Mysql = new Mysql()
mysql.insert()
mysql.delete() //因?yàn)殡[式轉(zhuǎn)換,mysql已經(jīng)是Operater類型峭弟,所以可以調(diào)用delete方法
}
}
class Operater{
def delete(): Unit ={
println("刪除方法 ...")
}
}
class Mysql{
def insert(): Unit ={
println("插入方法 ...")
}
}
3附鸽、隱式值與隱式參數(shù)
object Scala03_implicit {
def main(args: Array[String]): Unit = {
def test(name : String): Unit ={
println("hello "+name)
}
def test1(name : String = "lisi"): Unit ={
println("hello "+name)
}
implicit val username : String = "wangwu"
def test2(implicit name : String = "lisi"): Unit ={
println("hello "+name)
}
test("zhangsan") // hello zhangsan
test1() //hello lisi 入?yún)⒅付四J(rèn)值時(shí),可以不寫(xiě)入?yún)⒙魅常欢ㄒ獙?xiě)()
test2 // hello wangwu 使用隱式轉(zhuǎn)換,不要帶小括號(hào)
test2() // hello lisi 方法調(diào)用時(shí)使用小括號(hào)坷备,會(huì)導(dǎo)致隱式轉(zhuǎn)換無(wú)法傳遞
}
}
總結(jié):如果隱式參數(shù)存在默認(rèn)值、對(duì)應(yīng)參數(shù)的隱式值情臭,那么優(yōu)先采用隱士值省撑,如果找不到赌蔑,采用默認(rèn)值,再找不到竟秫,報(bào)錯(cuò)
4娃惯、隱式類
object Scala05_implicit {
def main(args: Array[String]): Unit = {
val user5:User5 = new User5()
user5.insert() // insert ...
user5.detele() // detele ...
}
// 1、隱式類相當(dāng)于包裝類
// 2鸿摇、有且只有一個(gè)參數(shù):需要報(bào)包裝的對(duì)象(值)
implicit class Person5(u:User5){
def detele(): Unit ={
println("detele ...")
}
}
class User5(){
def insert(): Unit ={
println("insert ...")
}
}
}
隱式類使用有如下幾個(gè)特點(diǎn):
1)其所帶的構(gòu)造參數(shù)有且只能有一個(gè)
2)隱式類必須被定義在“類”或“伴生對(duì)象”或“包對(duì)象”里石景,即隱式類不能是 頂級(jí)的(top-level objects)。
3)隱式類不能是case class(case class在后續(xù)介紹 樣例類)
4)作用域內(nèi)不能有與之相同名稱的標(biāo)識(shí)符
5拙吉、隱式轉(zhuǎn)換的解析機(jī)制(隱式轉(zhuǎn)換的搜索范圍)
即編譯器是如何查找到缺失信息的潮孽,解析具有以下兩種規(guī)則:
- 首先會(huì)在當(dāng)前代碼作用域下查找隱式實(shí)體(隱式方法、隱式類筷黔、隱式對(duì)象)往史。
- 如果第一條規(guī)則查找隱式實(shí)體失敗,會(huì)繼續(xù)在隱式參數(shù)的類型的作用域里查找佛舱。類型的作用域是指與該類型相關(guān)聯(lián)的全部伴生模塊椎例,一個(gè)隱式實(shí)體的類型T它的查找范圍如下(第二種情況范圍廣且復(fù)雜在使用時(shí),應(yīng)當(dāng)盡量避免出現(xiàn)):
a) 如果T被定義為T(mén) with A with B with C,那么A,B,C都是T的部分请祖,在T的隱式解析過(guò)程中订歪,它們的伴生對(duì)象都會(huì)被搜索。
b) 如果T是參數(shù)化類型肆捕,那么類型參數(shù)和與類型參數(shù)相關(guān)聯(lián)的部分都算作T的部分刷晋,比如List[String]的隱式搜索會(huì)搜索List的伴生對(duì)象和String的伴生對(duì)象。
c) 如果T是一個(gè)單例類型p.T慎陵,即T是屬于某個(gè)p對(duì)象內(nèi)眼虱,那么這個(gè)p對(duì)象也會(huì)被搜索。
d) 如果T是個(gè)類型注入S#T席纽,那么S和T都會(huì)被搜索捏悬。
//解釋b項(xiàng)
object Scala06_implicit {
def main(args: Array[String]): Unit = {
val user6:Users6 = new Users6()
user6.insert() // insert ...
user6.detele() // detele ...
}
class Users6() extends Test6 {
def insert(): Unit ={
println("insert ...")
}
}
}
trait Test6{
}
object Test6{
implicit class Person6(u:Users6){
def detele(): Unit ={
println("detele ...")
}
}
}