def foo(x:Int, f:Unit=>Int) = println(f())
foo(2, {Unit => 3+4}
//case1
def loop:Int = 7
foo(2, loop) //does not compile
changing loop to
//case 2
def loop():Int = 7
foo(2, loop) // does not compile
changing loop to
//case 3
def loop(x:Unit): Int = 7 //changing according to Don's Comments
foo(2,loop) // compiles and works fine
不应该是案例1,案例2也可以吗?他们为什么不工作?
将foo定义为
def foo(x:Int, y:()=>Int)
然后案例2有效,但不是案例1.
他们都不应该工作,无论如何定义功能。
//我也认为()=>在foo中Int是一个糟糕的样式,y:=> Int不起作用,评论??
答案 0 :(得分:82)
Scala区分以下事项:
这些都不是等价的,尽管为方便起见,Scala允许您省略空参数列表。 (顺便提一下,两个空参数列表也不相同。)
因此,即使Unit
被写为()
,但 与函数或方法的函数参数parens ()
相同。相反,请将()
视为Tuple0
。
所以,如果你说f: Unit => Int
,你的意思是“f取一个参数,但它是一个非常无聊的参数,因为它是Unit
,它必须始终是无聊的Tuple0
} value ()
“。你写的内容对于f: (Unit) => Int
来说真的很短。
如果你说f: () => Int
,那么你的意思是“f不带参数并产生Int
”。
如果你说f: => Int
,那么你的意思是“延迟任何语句的执行产生Int
值,直到我们在这段代码中使用它(并且每次都重新评估它)”。在功能上,这最终与f: () => Int
基本相同(并且内部转换为相同的Function0
类),但它有不同的用法,可能是为了允许更紧凑的闭包形式(你总是省略调用代码中的=>
。
答案 1 :(得分:14)
()=> Int是Function0 [Int],而Unit => Int是Function1 [Unit,Int]
scala> val function0: () => Int = () => 5
function0: () => Int = <function0>
scala> val function1: Unit => Int = u => 5
function1: (Unit) => Int = <function1>
scala> function0()
res0: Int = 5
scala> function1("anything")
res1: Int = 5
scala> function1(100)
res2: Int = 5
scala>
另请注意,()是Unit
的对象scala> function1(())
res11: Int = 5
scala> function1 ()
res12: Int = 5
scala> function1()
res13: Int = 5
scala> val unit = ()
unit: Unit = ()
scala> function1(unit)
res15: Int = 5
scala> function1 apply unit
res16: Int = 5
scala>
答案 2 :(得分:2)
在上面的情况1和2中,对于 foo 的第二个参数,类型检查循环的返回值而不是循环本身失败: Int!= Unit =&gt; Int
对循环的更改有错字。