Scala 中 implicit 的使用

Suraj P 2023年1月30日 2022年5月18日
  1. implicit 作为 Scala 中的参数值注入器
  2. implicit 作为 Scala 中的类型转换器
  3. implicit 作为 Scala 中的扩展方法
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 具有相同类型 intimplicit 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 作为参数并返回 intimplicit 函数。

这是另一个简单的例子。


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

这会导入我们想要从上面的代码中使用的定义的隐式类

Author: Suraj P
Suraj P avatar Suraj P avatar

A technophile and a Big Data developer by passion. Loves developing advance C++ and Java applications in free time works as SME at Chegg where I help students with there doubts and assignments in the field of Computer Science.

LinkedIn GitHub