Scala 中 implicit 的使用
本文将讨论 Scala 中 implicit
的不同用法。
implicit
作为 Scala 中的参数值注入器
在 Scala 中,隐式参数被传递给带有 implicit
关键字的方法。
这些值取自调用它们的上下文(范围)。简单来说,如果没有值或参数被传递给函数,那么编译器会寻找一个隐式
值并将其作为参数传递。
示例 1:
object MyClass {
def test(a:Int) = a
def main(args: Array[String]) {
test //calling the function but this gives error as no value is passed
}
}
这里我们调用了一个函数,没有传递任何参数值。这会导致错误。Scala 首先编译它;它试图传递一个值,但它不会得到参数的直接值。
示例 2:
object MyClass {
def test(implicit a:Int) = a
def main(args: Array[String]):Unit= {
test
}
}
这里我们调用了一个带有 implicit
关键字参数的函数。Scala 编译器将在同一范围内查找具有相同值类型的任何 val
。
如果找到,则编译成功;否则,我们会得到一个错误。因此,由于在同一类型的范围内没有值,因此上述程序会出错。
示例 3:
object MyClass {
def test(implicit a:Int) = a
implicit val b:Int =789
def main(args: Array[String]):Unit= {
println(test)
}
}
输出:
789
上面的代码运行成功是因为编译器找到了一个与函数中的隐式参数 a
具有相同类型 int
的 implicit val
。
implicit
作为 Scala 中的类型转换器
我们也可以使用 implicit
关键字来转换一种数据类型。
我们在下面的代码中将 string
转换为 int
类型。
object MyClass {
def main(args: Array[String]):Unit= {
val str :String = "hero"
val x:Int = str //we get error here
}
}
由于 string
不是 int
的子类型,它会出错。Scala 编译器在作用域中寻找一个以 string
作为参数并返回 int
的 implicit
函数。
这是另一个简单的例子。
object MyClass {
implicit def myfunc(a:String):Int = 500
def main(args: Array[String]):Unit= {
val str :String = "hero"
val x:Int = str // the compiler treats this as myfunc(str) and return 500
println(x)
}
}
输出:
500
上面的代码完美运行,因为当 Scala 编译器查找 implicit
函数时,它会找到 val x:Int = str
并将其视为 myfunc(str)
并返回 500。
implicit
作为 Scala 中的扩展方法
假设我们向整数对象添加一个新方法,将米转换为厘米。我们在对象内部创建一个隐式类
来实现这一点。
这个隐式类将只有一个构造函数参数。
下面是一个完整的代码示例,可以更好地理解它是如何工作的。
object MyObject {
implicit class mtoCm(m:Int){
def mToCm={
m*100
}
}
}
我们可以使用下面的代码来实现它。
import MyObject._
object workspace {
def main(args: Array[String]):Unit= {
println(3.mToCm) //calling the mtoCm from MyObject
}
}
输出:
300
这会导入我们想要从上面的代码中使用的定义的隐式类
。