没有参数的函数,在scala中将unit作为参数

时间:2010-05-05 15:21:53

标签: scala

 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不起作用,评论??

3 个答案:

答案 0 :(得分:82)

Scala区分以下事项:

  • 无参数列表的函数/方法(如果是函数,则为“by-name参数”)
  • 使用一个空参数列表
  • 的函数
  • 使用一个类型为
  • 的参数的函数

这些都不是等价的,尽管为方便起见,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

循环的更改有错字。