"implicit val"在 Scala 类定义中的含义是什么?



我正在努力加快Scala的速度,并且对关键字">隐式"的使用感到有些困惑。

我想我理解隐式参数的概念,其中参数没有显式传入,Scala 将搜索正确类型的值(在调用范围内(。

我对">隐式价值"的使用感到困惑。

请考虑以下代码片段:

case class DemoApp() {
implicit val foo = CustomerFoo()
}

这与传递给 DemoApp(( 类构造函数的参数有关吗?

有人可以澄清一下吗?

谢谢,约翰·

我想我理解隐式参数的概念,其中参数没有显式传入,

这只是硬币的另一面。

Scala 将搜索正确类型的值(在调用范围内(。

是的,但它不会只是接受任何随机值。只有显式标记为implicit的值。

implicit修饰符有四种用法,它们是成对相关的。

一对与隐式参数相关。当应用于参数列表中的参数时,implicit表示"不需要显式提供此参数,可以在调用的上下文中搜索"。当应用于valobject时,反过来,它意味着"这个值可以作为隐式参数传递"。

另一对与隐式转换有关。当implicit应用于具有一个参数的方法的方法定义时,它意味着"每当您需要返回类型的值,但只有参数类型的值时,可以使用此方法从参数值转换为返回值"。

例如,如果我有这样的东西:

implicit def string2Tuple2(s: String): (Int, Int) = {
val l = s.split(",")
(l(0).toInt, l(1).toInt)
}

然后,每当 Scala 期望一个(Int, Int)时,我也可以传递一个String,Scala 知道它可以调用string2Tuple来转换它:

val m = Map.empty[Int, Int]
m + "2,3"
//=> val res1: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3)

这当然是一个愚蠢的例子。一个更有用的示例是enrich-my-library 习惯用法,其中我们创建一个新类,该类使用一些新功能增强现有类,然后提供从旧类型到扩充类型的隐式转换:

class HelloString(s: String) {
val hello = "Hello " + s + " World"
}
implicit def string2HelloString(s: String) = new HelloString(s)
"beautiful".hello
//=> val res2: String = Hello beautiful World

这就是implicit修饰符的第二个用途。implicit类只是包装类的语法糖+隐式转换,这意味着上述内容完全等同于:

implicit class string2HelloString(s: String) {
val hello = "Hello " + s + " World"
}

这就是implicit修饰符在两个相关对中的四种用法。

相关内容

  • 没有找到相关文章

最新更新