Scala在面對編譯出現類型錯誤時,提供了一個由編譯器自我修復的機制,編譯器試圖去尋找一個隱式implicit
的轉換方法,轉換出正確的類型,完成編譯。這就是implicit
的意義。
一、 隱式轉換到某個期望類型
- 用在方法上
class ImplicitToMethod
object ImplicitToMethod {
//排除implicit的警告
import scala.language.implicitConversions
implicit def stringToInt(s: String): Int = Integer.parseInt(s)
implicit def typeConversion(input: Int): String = input.toString
implicit def typeConversion(input: Boolean): String = if (input) "true" else "false"
def plus(x: Int, y: Int): Int = x + y
def display(input: String): Unit = println(input)
def apply: ImplicitToMethod = new ImplicitToMethod()
}
- 測試
object ImplicitTest {
def main(args: Array[String]): Unit = {
//必須import隱式轉換的方法,否則出錯
import ImplicitToMethod.typeConversion
ImplicitToMethod.display("1212")
//編譯時調用了隱式轉換
ImplicitToMethod.display(12)
ImplicitToMethod.display(true)
import ImplicitToMethod.stringToInt
//編譯時調用了隱式轉換
val result = ImplicitToMethod.plus("3", "2")
println(result)
}
}
二、 隱式參數和隱式值形式
- 隱式參數
在函數中,將參數標誌出implicit,形式爲:
def func(implicit x: Int)
def func2(x: Int)(implicit y: Int)
def func3(implicit x: Int, y: Int)
這三種形式是有區別的,在參數中implicit只能出現一次,而在此之後,所有的參數都會變爲implicit
- 隱式值
implicit object Test
implicit val x = 5
implicit var y
- 作用
這種用法的作用主要是兩種用法搭配起來來達到一個效果,隱式參數表明這個參數是可以缺少的,也就是說在調用的時候這個參數可以不用出現,那麼這個值由什麼填充呢? 那就是用隱式的值。
object ImplicitToValue {
def funImplicit1(implicit age: Int): Unit = {
println("funImplicit1: age: " + age)
}
def funImplicit2(implicit age: Int, name: String): Unit = {
println("funImplicit2: age: " + age + ", name:" + name)
}
def funImplicit3(age: Int)(implicit name: String): Unit = {
println("funImplicit3: age: " + age + ", name:" + name)
}
}
- 測試
object ImplicitTest {
def main(args: Array[String]): Unit = {
implicit val impAge = 30
implicit val implName = "Jack"
funImplicit1
funImplicit2
funImplicit3(31)
}
}
三、 隱式類
- 形式
implicit class MyClass(x: Int)
- 作用
這裏的作用主要是其主構造函數可以作爲隱式轉換的參數,相當於其主構造函數可以用來當做一個implicit的function
class ImplicitToClass
object ImplicitToClass {
implicit class MyName(x: Int) {
val y = x
println("Test implicit class")
}
def say(x: MyName): Unit = {
println(x.y)
}
}
- 測試
object ImplicitTest {
def main(args: Array[String]): Unit = {
say(5)
}
}
這裏的MyName是一個隱式類,其主構造函數可以用作隱式轉換,所以say需要一個MyName類型的參數,但是調用的時候給的是一個Int,這裏就會調用MyName的主構造函數轉換爲一個MyName的對象,然後再println其y的值