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

sco*_*out 33 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
Run Code Online (Sandbox Code Playgroud)

案件1和案例2也不行吗?他们为什么不工作?

将foo定义为

def foo(x:Int, y:()=>Int)
Run Code Online (Sandbox Code Playgroud)

案例2有效但案例1无效.

他们都不应该工作,无论如何定义功能.

//也是我认为()=>在foo中的Int是一个糟糕的样式,y:=> Int不起作用,评论??

Rex*_*err 86

Scala区分以下事项:

  • 没有参数列表的函数/方法(如果是函数,则为"by-name参数")
  • 具有一个空参数列表的函数
  • 具有一个Unit类型参数的函数

这些都不是等价的,尽管为方便起见,Scala允许您忽略空参数列表.(顺便提一下,两个空参数列表也不相同.)

因此,即使Unit是写(),这是作为函数参数的括号相同()的函数或方法.相反,想象()一下Tuple0.

所以,如果你说f: Unit => Int,你的意思是"f需要一个参数,但它是一个非常无聊的参数,因为它Unit必须始终是相同的无聊Tuple0()".你写的东西真的很短f: (Unit) => Int.

如果你说f: () => Int,那么你的意思是"f不带参数并产生Int".

如果你说f: => Int,那么你的意思是"延迟任何语句的执行产生一个Int值,直到我们在这个代码中使用它(并且每次重新评估它)".在功能上,这最终基本上与f: () => Int(和内部转换为相同的Function0类)相同,但它有不同的用法,可能是为了允许更紧凑的闭包形式(你总是省略=>调用代码).

  • @ Jus12 - 的确如此.所有操作员角色之间的空间很重要.例如,`val x = -2`不起作用,因为虽然你可能认为`x`等于`-2`,解析器看到`x`,奇怪的运算符`= -`和`2`.`:`是"声明我的类型"运算符; `=>`是"函数生成此"运算符. (3认同)
  • @Scout:在这种情况下,没有理由添加多余的`Unit`.它对抽象很有用.假设你有一个组合函数:`def comp [A,B,C](f:A => B,g:B => C,a:A)= g(f(a))`并且你试图通过它是一个不返回值的`f`.那你现在怎么办?好吧,事实证明Scala总是_does_返回一些东西 - 至少是`()`(类型`Unit`唯一可能的值).所以现在你可以编写一个带有"Unit"类型输入的`g`并使用上面的一般组合函数.但是对于大多数情况,只需使用`def f()= ...`或`def f = ...`. (2认同)
  • 感谢您的澄清。我试图弄清楚如何进行惰性评估。请注意,“f: => Int”中“:”和“=”之间的空格很重要。 (2认同)

Eas*_*sun 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>
Run Code Online (Sandbox Code Playgroud)

还要注意()是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>
Run Code Online (Sandbox Code Playgroud)