(a: A, b: B, ..., z: Z) ?=> R 类型基本上意味着(using a: A, b: B, ..., z: Z) => R(我相信后一种语法在某一时刻有效,但现在不再有效)。当您使用?=> 时,所有这些参数都将成为隐式参数。类似地,函数字面量(a, b, ..., z) ?=> ... 使该函数的所有参数都隐式化,并且它们可以在以后隐式传递给其他方法。
这是一个示例 (Scastie):
case class Foo(s: String)
case class Bar(i: Int)
def baz(xyzzy: (Foo, Bar) ?=> String): Unit =
val foo = Foo("waldo")
val bar = Bar(2)
println(xyzzy(using foo, bar))
baz 采用上下文函数。注意xyzzy 是如何使用与普通方法相同的语法调用的而不是像 Scala 2 中那样简单地 blah(bleh, bluh))。
这是我们调用baz 的一种方式,通过定义一个带有隐式参数的方法:
def foobar(using Foo, Bar) =
val foo = summon[Foo]
val bar = summon[Bar]
s"Method - foo: $foo, bar: $bar"
baz(foobar)
我们也可以传入一个函数字面量。没有常规参数,所以它看起来有点像按名称参数。由于文字的 (Foo, Bar) ?=> 类型,存在 Foo 和 Bar 的隐式实例。
baz {
val foo = summon[Foo]
val bar = summon[Bar]
s"Function literal - foo: $foo, bar: $bar"
}
您还可以在函数文字本身中使用?=> 来命名隐式参数,而无需调用它们并将它们分配给值。由于它们是隐式的,因此您也可以从上面调用 foobar,因为隐式 Foo 和 Bar 可用(尽管没有显式命名参数,您也可以在第二个示例中执行此操作)。
baz { (foo: Foo, bar: Bar) ?=>
val fromMethod = foobar
s"Explicit context function literal - foo: $foo, bar: $bar; $fromMethod"
}