一:简介
隐式转换使用关键字implicit来修饰,隐式转换的命名方式是"源数据类型2目标数据类型",隐式转换的作用是自动的将源数据类型转为目标数据类型。
隐式转换可用于函数和值
二:示例
示例1
class Foo(var name: String)
class Bar(var name: String)
class Foobar(var name: String)
class Foobaz {
def test(foobar: Foobar): Unit = {
println("test")
}
}
object Main {
def main(args: Array[String]): Unit = {
// 注意:Foo、Bar、Foobar 三个类时独立的没有任何关系
var foo = new Foo("foo")
var baz = new Bar("bar")
var foobaz = new Foobaz
// test(foobar: Foobar) test方法接收的参数类型为Foobar类型,这里传的是Foo类型,编译器不报错
// 不报错的原因是Scala会检查有没有一种函数名叫foo2Foobar的,没有找到但是找到了any2Foobar也是满足条件的
// 就自动将传递的参数转化为Foobar类型
foobaz.test(foo)
}
// 隐式转换:转换是隐式的,怎么转换是自己显式的定义出来的
implicit def any2Foobar(any: Any): Foobar = {
if (any.isInstanceOf[Foo]) {
val foo = any.asInstanceOf[Foo]
new Foobar(foo.name)
} else if (any.isInstanceOf[Bar]) {
val bar = any.asInstanceOf[Bar]
new Foobar(bar.name)
} else {
null
}
}
}
全局implicit object类
class Foo(var name: String)
class Bar(var name: String)
class Foobar(var name: String)
class Foobaz {
def test(foobar: Foobar): Unit = {
println("test")
}
}
object Main333 {
def main(args: Array[String]): Unit = {
val foo = new Foo("foo")
val baz = new Bar("bar")
val foobaz = new Foobaz
import ImplicitUtil.any2Foobar
foobaz.test(foo)
}
}
// 可将需要隐式转换的函数或者变量封装到一个全局的object类中,在使用的时候通过import导入进来即可
object ImplicitUtil {
implicit def any2Foobar(any: Any): Foobar = {
if (any.isInstanceOf[Foo]) {
val foo = any.asInstanceOf[Foo]
new Foobar(foo.name)
} else if (any.isInstanceOf[Bar]) {
val bar = any.asInstanceOf[Bar]
new Foobar(bar.name)
} else {
null
}
}
}
示例2
class HtmlString(var str: String) {
def sout(): Unit = {
println("<H1>" + str + "</H1>")
}
}
object Main {
// 将String自动转换为HtmlString类型
implicit def stringToBase(str: String): HtmlString = new HtmlString(str)
def main(args: Array[String]): Unit = {
val string = "Hello"
// String并没有sout方法,而是将String转为HtmlString, 此时相当于String继承了HtmlString,可以调用任意公有的方法
// 这种用法用于对类的增强,让一个类具有另一个类的方法而不用去继承
string.sout()
}
}
隐式参数
class Foo {
def sout(value: String): Unit = {
println(value)
}
}
object Main {
// 定义了两个参数:被implicit修饰的参数称之为隐式参数
def test(name: String)(implicit foo: Foo): Unit = {
foo.sout(name)
}
def main(args: Array[String]): Unit = {
implicit val foo = new Foo
// 隐式参数不需要显式传值,系统会将使用implicit修饰的变量作为参数传递过去
test("mengday")
}
}