Scala基础应用(9)- 隐式转换
首先要明确隐式转换只针对类型,与名称无关,我把隐式类型分为以下三类
- 隐式参数
- 隐式方法
- 隐式类
注意:隐式转换只发生在运行时当前上下文没有对应的调用。
同时,隐式转换有如下限制:
- 不存在二义性, 即对同一类型不能有两种隐式转换
- 不能嵌套使用,如:convert1(convert2(x))) + y
- 如果有对应的非隐式存在,则隐式不会执行
下面为大家一一讲解
隐式参数
也可称为隐式值,即为隐式参数赋值
implicit val myname = "Mark Zhou"
def whoami(implicit name: String) = "My name is " + name
whoami
隐式方法
或者叫隐式类型,它可以将一种类型转换成另外一种类型
class Person(name: String, age: Int) {
def detail = s"My name is $name and my age is $age"
}
import scala.language.implicitConversions
import scala.language.postfixOps
implicit def mydetail(name: String) = new Person(name, 18)
"Mark Zhou".detail
这里我们思考一下,"Mark Zhou".length会出现什么情况?查看开始部分的“注意”项。
隐式类
Scala 2.10后才开始提供隐式类,同时隐式类有一些限制:
- 隐式类必须被定义在特质,类和伴生对象里
- 有且仅有一个构造参数
- 作用域内不能有同名方法,变量或者伴生对象
- 不能是case class (case class 会自动产生伴生类,违反第3条)
object ImplicitClassDemo {
implicit class MyClass(private val name: String) {
def detail = s"My name is $name and my age is 18"
}
}
import ImplicitClassDemo._
"Mark Zhou".detail
隐式查找规则
- 首先在当前作用域内查找隐式
- 其次会在参数的作用域内查找隐式, 即在与该参数类型相关联的全部伴生模块里查找,如类型T
- 如果T被定义为T with TypeA with TypeB with TypeC, 那么TypeA, TypeB 以及TypeC都是T的关联部分,这些类型的伴生对象都是查找对象
- 如果T被定义为参数化类型,则会查找该类型相关联的部分,如List[Int] 会查找List和Int的伴生对象
- 如果T被定义在某个伴生对象内,则该伴生对象和T都会被查找
- 如果T类型注入S#T, 则S和T都会被查找