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的值