隐式转换函数_隐函数可以转化为显函数
隱式轉換函數(implicit conversion function)是以implicit關鍵字聲明的帶有單個參數的函數,這樣的函數將被自動應用,將值從一種類型轉換為另一種類型。隱式轉換函數叫什么名字是無所謂的,因為通常不會由用戶手動調用,而是由Scala進行調用。但是如果要使用隱式轉換,則需要對隱式轉換函數進行導入。因此通常建議將隱式轉換函數的名稱命名為“one2one”的形式。
scala會考慮如下位置的隱式轉換函數:
1、位于源或目標類型的伴生對象中的隱式函數
2、位于當前作用域可以以單個標識符指代的隱式函數
隱式轉換在如下三種不同情況下會被考慮:
1、當表達式類型與預期類型不同時
2、當對象訪問一個不存在成員時
3、當對象調用某個方法,而這個方法的參數聲明與傳入參數不匹配時
有三種情況編譯器不會嘗試使用隱式轉換
1、如果代碼能夠在不使用隱式轉換的前提下通過編譯,則不會使用隱式轉換
2、編譯器不會嘗試同事執行多個轉換
3、存在二義性的轉換是錯誤。
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}
}
隱式轉換的注意事項和細節
1、隱式轉換函數的函數名可以是任意的,隱式轉換與函數名稱無關,只與函數簽名(函數參數類型和返回值類型)有關。
2、隱式函數可以有多個(即:隱式函數列表),但是需要保證在當前環境下,只有一個隱式函數能被識別
隱式參數
定義
1、定義一個普通變量,使用 implicit 關鍵字修飾,定義一個函數調用這個變量當參數時,此時這個參數就被稱為隱式參數
2、隱式參數的作用:減少提供函數參數的數量,讓某些參數擁有隱藏的值(隱式變量)
def main(args: Array[String]): Unit = {
//隱式參數(每種類型只能有一個)
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
}
//優先級:傳參 > 隱式參數 > 默認
println("fun結果:"+fun(10,10)) //30 調用隱式參數10 //25 默認賦值5
println("fun結果:"+fun(10,10)(20)) //40 傳參20
println("fun2結果:"+fun2(10,10)(20))
println("fun3結果:"+fun3(10,10))
println("fun3結果:"+fun3(10,10)(20,"heheda"))
}
隱式類
基本介紹
在scala2.10后提供了隱式類,可以使用implicit聲明類,隱式類的非常強大,同樣可以擴展類的功能,比前面使用隱式轉換豐富類庫功能更加的方便,在集合中隱式類會發揮重要的作用。
隱式類使用有如下幾個特點:
其所帶的構造參數有且只能有一個
隱式類必須被定義在“類”或“伴生對象”或“包對象”里,即隱式類不能是 頂級的(top-level objects)。
隱式類不能是case class(case class在后續介紹 樣例類)
作用域內不能有與之相同名稱的標識符
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")
}
}
轉換時機
當方法中的參數的類型與目標類型不一致時
當對象調用所在類中不存在的方法或成員時,編譯器會自動將對象進行隱式轉換(根據類型)
隱式解析機制
即編譯器是如何查找到缺失信息的,解析具有以下兩種規則:
首先會在當前代碼作用域下查找隱式實體(隱式方法、隱式類、隱式對象)。(一般是這種情況)
如果第一條規則查找隱式實體失敗,會繼續在隱式參數的類型的作用域里查找。類型的作用域是指與該類型相關聯的全部伴生模塊,一個隱式實體的類型T它的查找范圍如下(第二種情況范圍廣且復雜在使用時,應當盡量避免出現):
a) 如果T被定義為T with A with B with C,那么A,B,C都是T的部分,在T的隱式解析過程中,它們的伴生對象都會被搜索。
b) 如果T是參數化類型,那么類型參數和與類型參數相關聯的部分都算作T的部分,比如List[String]的隱式搜索會搜索List的伴生對象和String的伴生對象。
c) 如果T是一個單例類型p.T,即T是屬于某個p對象內,那么這個p對象也會被搜索。
d) 如果T是個類型注入S#T,那么S和T都會被搜索。
隱式轉換的前提
在進行隱式轉換時,需要遵守兩個基本的前提:
不能存在二義性
隱式操作不能嵌套使用 // [舉例:]如:隱式轉換函數
總結
以上是生活随笔為你收集整理的隐式转换函数_隐函数可以转化为显函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JVM优化之优化常用参数和工具
- 下一篇: react全家桶包括哪些_react 自