隱式轉換是在Scala編譯器進行類型匹配時,如果找不到合適的類型,那麼隱式轉換會讓編譯器在作用範圍內自動推導出來合適的類型。
隱式值是指在定義參數時前面加上implicit。隱式參數是指在定義方法時,方法中的部分參數是由implicit修飾【必須使用柯里化的方式,將隱式參數寫在後面的括號中】。隱式轉換作用是:當呼叫方法時,不必手動傳入方法中的隱式參數,Scala會自動在作用域範圍內尋找隱式值自動傳入。
隱式值和隱式參數需要注意以下幾點:
1.同類型的參數的隱式值只能在作用域內出現一次,同一個作用域內不能定義多個類型一樣的隱式值。2.implicit關鍵字必須放在隱式參數定義的開頭
3.一個方法只有一個參數是隱式轉換參數時,那麼可以直接定義implicit關鍵字修飾的參數,呼叫時直接建立類型不傳入參數即可。
4.一個方法如果有多個參數,要實現部分參數的隱式轉換,必須使用柯里化這種方式,隱式關鍵字出現在後面,只能出現一次
package com.bjsxt.scala object ImplicitValue { /** * 隐式值和隐式参数需要注意以下几点: * 1.同类型的参数的隐式值只能在作用域内出现一次,同一个作用域内不能定义多个类型一样的隐式值。 * 2.implicit关键字必须放在隐式参数定义的开头 * 3.一个方法只有一个参数是隐式转换参数时,那么可以直接定义implicit关键字修饰的参数,调用时直接创建类型不传入参数即可。 * 4.一个方法如果有多个参数,要实现部分参数的隐式转换,必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次 */ // * 4.一个方法如果有多个参数,要实现部分参数的隐式转换, // 必须使用柯里化这种方式,隐式关键字出现在后面,只能出现一次 def Student(age:Int)(implicit name:String,i:Int) = { println(s"student = $name,age = $age,score = $i") } // * 3.一个方法只有一个参数是隐式转换参数时,那么可以直接定义implicit关键字修饰的参数, // 调用时直接创建类型不传入参数即可。 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()這個方法,發現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的隱式轉換怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!