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

时间:2018-02-10 00:27:24

标签: scala implicit default-parameters

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的默认值)将评估为{{1}},而不必传递参数明确地

2 个答案:

答案 0 :(得分: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()表示“使用所有参数的默认值调用foo”,foo表示“调用foo,传递隐式参数列表”。

因此,对于bar(implicit j: Int) = foo,它会评估为j的值,而bar(implicit j: Int) = foo()的评估结果为1.

答案 1 :(得分:0)

Scala编译器在implicit和默认值之间混淆。 foo()使编译器忽略implicit。所以只有foo才能解决这个问题

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

println(bar(5))
  

结果:5