Scala - 为什么在隐式列表之前声明一个空参数列表

时间:2015-02-28 20:36:34

标签: scala implicit

某些地方(例如Play Form.bindFromRequest)在隐式参数列表之前使用空参数列表。为什么? 恕我直言,它的缺点是在form.bindFromRequest()(request)中明确传递参数时需要额外的括号。 不知道那么有什么优势呢?

1 个答案:

答案 0 :(得分:1)

具有参数列表的def与不具有参数列表的类型具有不同的类型。这在直接调用下无关紧要,但如果将该方法作为参数传递给另一个方法,则确实如此。

例如,如果您定义方法如下:

def func1 = { println("Hello"); 1 }

您无法将其传递给此方法:

def consume(f: () => Double) = // ...

因为它的类型只是Double,尽管它非常懒惰。另一方面,这个功能可以正常工作:

def func2() = { println("Hello"); 2 }

我不是说这是他们为什么这么做的明确原因,但如果他们有实际的理由,那几乎肯定会与类型挂钩。

编辑:

它们之间的区别实际上它主要归结为可以使用的地方。

按值调用项目只能在参数列表中用于函数/方法(afaik)。由于它只能在参数列表中传递,因此您无法将其存储在变量中并在多个位置使用它(无需将其更改为T的显式实例)。

正如你在这里看到的,它们本身不可互换:

scala> def f(s: => String) { println(s) }
f: (s: => String)Unit

scala> def s1 = () => { "Hello" }
s1: () => String

scala> f(s1)
<console>:10: error: type mismatch;
 found   : () => String
 required: String
              f(s1)
                ^

想象一下,我想存储一组用户传递给我的回调..我不能在这里使用=> T

scala> val a: Array[=> Int] = Array()
<console>:1: error: identifier expected but '=>' found.
       val a: Array[=> Int] = Array()
                    ^

scala> val a: Array[() => Int] = Array()
a: Array[() => Int] = Array()

因此,如果我想存储这些项目,并在内部传递它们,使用=> T(并保持懒惰评估)不是一种选择。

我认为最好不要将=>=> T中的() => T视为同一件事。希望这有点帮助。