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

What is the meaning of "implicit val" in a Scala class definition?

我正在努力跟上 Scala 的速度,但对关键字“implicit”的用法有点困惑。

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

我对“隐式值”的使用感到困惑。

考虑以下代码片段:

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

这是否与传递给 DemoApp() class 构造函数的参数有关?

有人可以澄清一下吗?

谢谢,JohnB

think I understand the notion of implicit parameters, where the parameters are not explicitly passed in,

这只是硬币的另一面。

Scala will search for a value of the correct type (within the calling scope).

是的,但它不会只取 任何 随机值。 只有 个明确标记的值 implicit

一个implicit修饰符有四种用法,成对相关。

一对与隐式参数相关。当应用于参数列表中的参数时,implicit 表示“不需要显式提供此参数,可以在调用的上下文中搜索它”。当应用于 valobject 时,依次表示“此值可以作为隐式参数传递”。

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

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

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,用一些新功能增强现有的 class,然后提供从旧类型到丰富类型的隐式转换:

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 class 只是包装器 class + 隐式转换的语法糖,意思是上面的完全等同于:

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

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