隐式转换函数_隐函数可以转化为显函数
隱式轉(zhuǎn)換函數(shù)(implicit conversion function)是以implicit關(guān)鍵字聲明的帶有單個(gè)參數(shù)的函數(shù),這樣的函數(shù)將被自動(dòng)應(yīng)用,將值從一種類型轉(zhuǎn)換為另一種類型。隱式轉(zhuǎn)換函數(shù)叫什么名字是無(wú)所謂的,因?yàn)橥ǔ2粫?huì)由用戶手動(dòng)調(diào)用,而是由Scala進(jìn)行調(diào)用。但是如果要使用隱式轉(zhuǎn)換,則需要對(duì)隱式轉(zhuǎn)換函數(shù)進(jìn)行導(dǎo)入。因此通常建議將隱式轉(zhuǎn)換函數(shù)的名稱命名為“one2one”的形式。
 scala會(huì)考慮如下位置的隱式轉(zhuǎn)換函數(shù):
1、位于源或目標(biāo)類型的伴生對(duì)象中的隱式函數(shù)
2、位于當(dāng)前作用域可以以單個(gè)標(biāo)識(shí)符指代的隱式函數(shù)
隱式轉(zhuǎn)換在如下三種不同情況下會(huì)被考慮:
1、當(dāng)表達(dá)式類型與預(yù)期類型不同時(shí)
2、當(dāng)對(duì)象訪問(wèn)一個(gè)不存在成員時(shí)
3、當(dāng)對(duì)象調(diào)用某個(gè)方法,而這個(gè)方法的參數(shù)聲明與傳入?yún)?shù)不匹配時(shí)
有三種情況編譯器不會(huì)嘗試使用隱式轉(zhuǎn)換
1、如果代碼能夠在不使用隱式轉(zhuǎn)換的前提下通過(guò)編譯,則不會(huì)使用隱式轉(zhuǎn)換
2、編譯器不會(huì)嘗試同事執(zhí)行多個(gè)轉(zhuǎn)換
3、存在二義性的轉(zhuǎn)換是錯(cuò)誤。
object Demo1Main { 
   
  def main(args: Array[String]): Unit = { 
   
    val num:Int = f1(3.5);
    val num1:Int = 3.5;
      print(num)
  }
  implicit def f1(d: Double): Int = { 
   d.toInt}
}
隱式轉(zhuǎn)換的注意事項(xiàng)和細(xì)節(jié)
1、隱式轉(zhuǎn)換函數(shù)的函數(shù)名可以是任意的,隱式轉(zhuǎn)換與函數(shù)名稱無(wú)關(guān),只與函數(shù)簽名(函數(shù)參數(shù)類型和返回值類型)有關(guān)。
2、隱式函數(shù)可以有多個(gè)(即:隱式函數(shù)列表),但是需要保證在當(dāng)前環(huán)境下,只有一個(gè)隱式函數(shù)能被識(shí)別
隱式參數(shù)
定義
 1、定義一個(gè)普通變量,使用 implicit 關(guān)鍵字修飾,定義一個(gè)函數(shù)調(diào)用這個(gè)變量當(dāng)參數(shù)時(shí),此時(shí)這個(gè)參數(shù)就被稱為隱式參數(shù)
 2、隱式參數(shù)的作用:減少提供函數(shù)參數(shù)的數(shù)量,讓某些參數(shù)擁有隱藏的值(隱式變量)
def main(args: Array[String]): Unit = { 
   
   //隱式參數(shù)(每種類型只能有一個(gè))
    implicit var a:Int = 10
    implicit var str:String = "hello"
    def fun(a:Int,b:Int)(implicit c:Int=5):Int={ 
   
      a+b+c
    }
    def fun2(a:Int,b:Int)(c:Int):Int={ 
   
      a+b+c
    }
    def fun3(a:Int,b:Int)(implicit c:Int=5,str:String):Int={ 
   
      println(str)
      a+b+c
    }
    //優(yōu)先級(jí):傳參 > 隱式參數(shù) > 默認(rèn)
    println("fun結(jié)果:"+fun(10,10))   //30 調(diào)用隱式參數(shù)10 //25 默認(rèn)賦值5
    println("fun結(jié)果:"+fun(10,10)(20)) //40 傳參20
    println("fun2結(jié)果:"+fun2(10,10)(20))
    println("fun3結(jié)果:"+fun3(10,10))
    println("fun3結(jié)果:"+fun3(10,10)(20,"heheda"))
}
隱式類
基本介紹
在scala2.10后提供了隱式類,可以使用implicit聲明類,隱式類的非常強(qiáng)大,同樣可以擴(kuò)展類的功能,比前面使用隱式轉(zhuǎn)換豐富類庫(kù)功能更加的方便,在集合中隱式類會(huì)發(fā)揮重要的作用。
隱式類使用有如下幾個(gè)特點(diǎn):
其所帶的構(gòu)造參數(shù)有且只能有一個(gè)
 隱式類必須被定義在“類”或“伴生對(duì)象”或“包對(duì)象”里,即隱式類不能是 頂級(jí)的(top-level objects)。
 隱式類不能是case class(case class在后續(xù)介紹 樣例類)
 作用域內(nèi)不能有與之相同名稱的標(biāo)識(shí)符
package com.liu.yinshi
object Demo2Main { 
   
  def main(args: Array[String]): Unit = { 
   
    implicit class DB1(val mysql: Mysql) { 
   
      def addSufix(): String = { 
   
        mysql.driver + " scala"
      }
    }
    val mysql = new Mysql;
    val str = mysql.addSufix()
    println(str)
  }
}
package com.liu.yinshi
class Mysql { 
   
  val driver = "mysqlDriver"
  def insert(): Unit ={ 
   
    print("insert function")
  }
  def sayOk(): Unit ={ 
   
    println("sayOk")
  }
}
轉(zhuǎn)換時(shí)機(jī)
當(dāng)方法中的參數(shù)的類型與目標(biāo)類型不一致時(shí)
 當(dāng)對(duì)象調(diào)用所在類中不存在的方法或成員時(shí),編譯器會(huì)自動(dòng)將對(duì)象進(jìn)行隱式轉(zhuǎn)換(根據(jù)類型)
隱式解析機(jī)制
即編譯器是如何查找到缺失信息的,解析具有以下兩種規(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ì)被搜索。
隱式轉(zhuǎn)換的前提
在進(jìn)行隱式轉(zhuǎn)換時(shí),需要遵守兩個(gè)基本的前提:
不能存在二義性
 隱式操作不能嵌套使用 // [舉例:]如:隱式轉(zhuǎn)換函數(shù)
總結(jié)
以上是生活随笔為你收集整理的隐式转换函数_隐函数可以转化为显函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: JVM优化之优化常用参数和工具
 - 下一篇: react全家桶包括哪些_react 自