Java Scala的隱式轉換詳解
隱式轉換是在Scala編譯器進行類型匹配時,如果找不到合適的類型,那么隱式轉換會讓編譯器在作用范圍內自動推導出來合適的類型。
一、隱式值與隱式參數
隱式值是指在定義參數時前面加上implicit。隱式參數是指在定義方法時,方法中的部分參數是由implicit修飾【必須使用柯里化的方式,將隱式參數寫在后面的括號中】。隱式轉換作用就是:當調用方法時,不必手動傳入方法中的隱式參數,Scala會自動在作用域范圍內尋找隱式值自動傳入。
隱式值和隱式參數需要注意以下幾點:
1.同類型的參數的隱式值只能在作用域內出現一次,同一個作用域內不能定義多個類型一樣的隱式值。2.implicit關鍵字必須放在隱式參數定義的開頭
3.一個方法只有一個參數是隱式轉換參數時,那么可以直接定義implicit關鍵字修飾的參數,調用時直接創(chuàng)建類型不傳入參數即可。
4.一個方法如果有多個參數,要實現部分參數的隱式轉換,必須使用柯里化這種方式,隱式關鍵字出現在后面,只能出現一次
package com.bjsxt.scala
object ImplicitValue {
/**
* 隱式值和隱式參數需要注意以下幾點:
* 1.同類型的參數的隱式值只能在作用域內出現一次,同一個作用域內不能定義多個類型一樣的隱式值。
* 2.implicit關鍵字必須放在隱式參數定義的開頭
* 3.一個方法只有一個參數是隱式轉換參數時,那么可以直接定義implicit關鍵字修飾的參數,調用時直接創(chuàng)建類型不傳入參數即可。
* 4.一個方法如果有多個參數,要實現部分參數的隱式轉換,必須使用柯里化這種方式,隱式關鍵字出現在后面,只能出現一次
*/
// * 4.一個方法如果有多個參數,要實現部分參數的隱式轉換,
// 必須使用柯里化這種方式,隱式關鍵字出現在后面,只能出現一次
def Student(age:Int)(implicit name:String,i:Int) = {
println(s"student = $name,age = $age,score = $i")
}
// * 3.一個方法只有一個參數是隱式轉換參數時,那么可以直接定義implicit關鍵字修飾的參數,
// 調用時直接創(chuàng)建類型不傳入參數即可。
def Teacher(implicit name:String) = {
println(s"teacher name is =$name")
}
def main(args: Array[String]): Unit = {
// * 1.同類型的參數的隱式值只能在作用域內出現一次,
// 同一個作用域內不能定義多個類型一樣的隱式值。比如這里的String、Int類型,各自只能定義一個
implicit val name:String = "zhangsan"
implicit val i:Int = 100
//這里使用了隱式參數,只用傳入age那個參數,后面兩個參數可以不填,默認使用隱式值
Student(100)
//這里是直接使用了隱式值,可以不填參數,當然也可以給定參數,給定參數的話就是取給的參數的值
Teacher
}
}輸出的結果:會自動尋找對應的函數,并且進行隱式轉換。
student = zhangsan,age = 100,score = 100 teacher name is =zhangsan
二、隱式轉換函數
隱式轉換函數是使用關鍵字implicit修飾的方法。當Scala運行時,假設如果A類型變量調用了method()這個方法,發(fā)現A類型的變量沒有method()方法,而B類型有此method()方法,會在作用域中尋找有沒有隱式轉換函數將A類型轉換成B類型,如果有隱式轉換函數,那么A類型就可以調用method()這個方法。
隱式轉換函數注意:隱式轉換函數只與函數的參數類型和返回類型有關,與函數名稱無關,所以作用域內不能有相同的參數類型和返回類型的不同名稱隱式轉換函數。
package com.bjsxt.scala
class Animal(name:String){
def canFly()= {
println(s"$name can fly....")
}
}
class Rabbit(xname:String){
val name = xname
}
object ImplicitValue2 {
//定義隱式轉換函數
implicit def RabbitToAnimal(r:Rabbit):Animal = {
new Animal(r.name)
}
//注意隱式轉換函數只與參數類型和返回值類型有關,
// 與函數名無關,所以不能定義兩個相同類型的函數,雖然函數名不同,下面這個就是非法的
// implicit def Rabbit(r:Rabbit):Animal = {
// new Animal(r.name)
// }
def main(args: Array[String]): Unit = {
val rabbit = new Rabbit("rabbit")
//這里rabbit調用不了canFly,因為Rabbit類中沒有canFly方法,
// 但定義了隱式轉換函數,那就會往Animal類中找
rabbit.canFly()
}
}運行結果:
rabbit can fly....
三、隱式類
使用implicit關鍵字修飾的類就是隱式類。若一個變量A沒有某些方法或者某些變量時,而這個變量A可以調用某些方法或者某些變量時,可以定義一個隱式類,隱式類中定義這些方法或者變量,隱式類中傳入A即可。
隱式類注意:
1.隱式類必須定義在類,包對象,伴生對象中
2.隱式類的構造必須只有一個參數,同一個類,包對象,伴生對象中不能出現同類型構造的隱式類。
package com.bjsxt.scala
//隱式類
class Rabbit1(xname:String){
val name = xname
}
object ImplicitValue3 {
//定義隱式類,只能在object中定義,并且只能傳入一個參數
//不能出現同類型構造的隱式類。(同類型:參數類型和返回值類型,與類名無關)
implicit class Animal1(r:Rabbit1){
def showName() = {
println(s"${r.name} is Rabbit....")//對象.屬性需要加“{}”
}
}
def main(args: Array[String]): Unit = {
val rabbit = new Rabbit1("RABBIT")
// Rabbit1類中沒有showName方法,這是會找隱式類
rabbit.showName()
}
}運行結果:
RABBIT is Rabbit....
到此這篇關于Java Scala的隱式轉換詳解的文章就介紹到這了,更多相關Scala隱式轉換內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring Boot構建優(yōu)雅的RESTful接口過程詳解
這篇文章主要介紹了spring boot構建優(yōu)雅的RESTful接口過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08
Spring @Cacheable redis異常不影響正常業(yè)務方案
這篇文章主要介紹了Spring @Cacheable redis異常不影響正常業(yè)務方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-02-02

