如果我们有一个接受匿名函数A => B作为参数的方法,我们可以A在调用中隐式.
def impl(a: Int)(f: Int => Int): Int = f(a)
impl(a) { implicit z =>
...
}
Run Code Online (Sandbox Code Playgroud)
但是我们可以使用具有多个参数的匿名函数来执行此操作吗?
def impl(a: Int, b: Int)(f: (Int, Int) => Int): Int = f(a, b)
Run Code Online (Sandbox Code Playgroud)
理想情况下,这将工作如下:
impl(1, 2) { implicit (a, b) => // wrong
...
}
Run Code Online (Sandbox Code Playgroud)
要么
impl(1, 2) { (implicit a, implicit b) => // also wrong
...
}
Run Code Online (Sandbox Code Playgroud)
我可以使用A => B => C相反的方法解决这个问题:
def impl(a: Int, b: Int)(f: Int => Int => Int): Int = f(a)(b)
impl(1, 2) { implicit a => implicit b =>
...
}
Run Code Online (Sandbox Code Playgroud)
但有没有一种方法可以做到这一点,而不必担心功能?
这应该是显而易见的,但这Int只是一个虚拟的占位符.
不,这不可能。从规范的第6.23节匿名函数中,匿名函数语法是:
Expr ::= (Bindings | ['implicit'] id | '_') '=>' Expr
ResultExpr ::= (Bindings | (['implicit'] id | '_') ':' CompoundType) '=>' Block
Bindings ::= '(' Binding {',' Binding} ')'
Binding ::= (id | '_') [':' Type]
Run Code Online (Sandbox Code Playgroud)
正如可以看到,该implicit情况下是特别套管仅具有1点的标识符,而重复的情况下Bindings(使用重复语法{...}的EBNF)排除了使用的implicit。
implicit本节中唯一添加的详细信息是:
匿名函数的命名参数可以选择在隐式修饰符之前。在这种情况下,参数被标记为隐式;然而,参数部分本身并不算作此处定义的隐式参数部分。因此,匿名函数的参数总是必须明确给出。
我认为这段文字还应该澄清这仅适用于单个参数(例如“具有恰好 1 个参数的匿名函数的命名参数......”)
当然,最简单的解决方法是避开语法糖并将匿名函数参数重新绑定到新的隐式变量:
impl(a) { (b, c) =>
implicit val (impB, imbC) = (b, c)
...
}
Run Code Online (Sandbox Code Playgroud)