默认参数值总是胜过 Scala 中的隐含值吗?

Do default parameter values always trump implicits in Scala?

def foo(implicit i: Int = 1) = i
def bar(implicit j: Int) = foo()

bar(4)

这段代码的计算结果为 1。所以默认值优先于隐式 j,它被实例化为 4。因此,看起来,至少在这个例子中,默认参数值胜过 implicit,使得 foo 的定义等同于 def foo(i: Int = 1) = i.

默认参数值总是胜过隐式吗?如果是,为什么这段代码是合法的(鉴于它令人困惑)?如果不是,反例是什么?

有没有办法获得其他行为,即与上面类似的一段代码(i 的默认值)将评估为 4,而不必通过明确论点?

implicit 应用于整个参数列表,而不仅仅是单个参数(例如,您可以使用 foo(implicit i: Int, j: Int),并且两个参数都是隐式的,但是,如果您只想要其中一个实际上,您必须将它们分成两个列表:def foo(i: Int)(implicit j: Int).

因此,要将隐式参数传递给函数,您必须省略整个列表:foo,而不是 foo()

当你有 def foo(implicit i: Int) 时,foo() 甚至不会编译,因为你正试图向列表发送一个空参数。 foo 会(只要隐式 int 在范围内),因为列表是隐式传递的。

def foo(implicit i: Int = 1)一样,都用compile,意思不一样。 foo() 表示 "call foo with default values for all parameters",foo 表示 "call foo, passing the implicit parameter list"。

因此,对于 bar(implicit j: Int) = foo,它将评估为 j 的值,而 bar(implicit j: Int) = foo() 评估为 1。

Scala 编译器混淆了 implicit 和默认值。 foo() 使编译器忽略 implicit。所以 foo 就可以做到这一点

def foo(implicit i: Int = 1) = i
def bar(implicit j: Int) = foo

println(bar(5))

Result : 5