Python Scala`def loop():Unit=loop`,为什么要永远循环?

Python Scala`def loop():Unit=loop`,为什么要永远循环?,python,scala,Python,Scala,在斯卡拉 def loop(): Unit = loop 当你称之为: loop() loop() 它将永远循环。我不明白为什么 例如,在Python中: def loop(): return loop 当你称之为: loop() loop() 它回来了 <function loop at 0x7f276e680668> 它返回一个空行: () 从Scala: “Scala允许在arity-0方法上省略括号(无参数): 但是,仅当所讨论的方法没有副作用(

在斯卡拉

def loop():
   Unit = loop
当你称之为:

loop()
loop()
它将永远循环。我不明白为什么

例如,在Python中:

def loop():
    return loop
当你称之为:

loop()
loop()
它回来了

<function loop at 0x7f276e680668>
它返回一个空行:

()
从Scala:

“Scala允许在arity-0方法上省略括号(无参数):

但是,仅当所讨论的方法没有副作用(纯功能性)时才应使用此语法。换句话说,在调用queue.size时可以省略括号,但在调用println()时则不能。此约定反映了上述方法声明约定

严格遵守这一惯例将极大地提高代码可读性,并使任何给定方法的最基本操作一目了然变得更容易理解。请不要为了保存两个字符而忽略括号!

从Scala:

“Scala允许在arity-0方法上省略括号(无参数):

但是,仅当所讨论的方法没有副作用(纯功能性)时才应使用此语法。换句话说,在调用queue.size时可以省略括号,但在调用println()时则不能。此约定反映了上述方法声明约定


严格遵守此约定将极大地提高代码的可读性,并使任何给定方法的最基本操作更容易一目了然。请不要为了保存两个字符而忽略括号!

您可以忽略括号,它将不带参数地调用函数。它不像Python。

可以省略括号,它调用函数时不带参数。它不像Python。

在Scala中,不带参数的方法可以使用括号调用,也可以不使用括号调用,但只有在使用括号定义的情况下才能调用

def one() = 1
def two = 2

one    // 1
one()  // 1
two    // 2
two()  // error: Int does not take parameters

来自
println(println())
()
输出有点不同。
println()
语句返回的
Unit
是一种只有一个可能值的类型,在Scala中表示为
()

,不带参数的方法可以在带括号或不带括号的情况下调用,但只有在用括号定义时才可以调用

def one() = 1
def two = 2

one    // 1
one()  // 1
two    // 2
two()  // error: Int does not take parameters

来自
println(println())
()
输出有点不同。
println()
语句返回
Unit
,该类型只有一个可能的值,表示为
()

,也可以在Scala中获取对非匿名函数的引用。例如,这里我们有两个功能:

def callFunc(f: Unit => Unit): Unit = f()
def printUnit(x: Unit): Unit = println(x)
第一个函数接受对另一个函数的引用,该函数返回
Unit
,调用该函数并返回结果
Unit
,而第二个函数获取
Unit
类型的值,打印它,并返回
Unit

例如,以下编译:

callFunc(printUnit)
正如这一点:

printUnit(callFunc(printUnit))
但不是这个:

callFunc(printUnit())
为什么??因为
callFunc
引用了一个签名为
Unit=>Unit
的函数,而
printUnit
满足了这个条件,所以编译器认为我们必须使用
对象。然后返回一个typ
Unit
,该值
printUnit
接受并打印

但是,如果我们在
printUnit
之后附加paren,我们会显式地调用它,返回
Unit
。因此第三个示例没有编译,因为
callFunc
只引用函数,它不接受类型为
Unit
的简单值

如果要显式引用编译器无法派生该意图的函数,可以使用:

但是,如果您明确说明了类型,编译器可以自己解决:

val f: () => Unit = loop

也可以在Scala中获得对非匿名函数的引用。例如,这里我们有两个功能:

def callFunc(f: Unit => Unit): Unit = f()
def printUnit(x: Unit): Unit = println(x)
第一个函数接受对另一个函数的引用,该函数返回
Unit
,调用该函数并返回结果
Unit
,而第二个函数获取
Unit
类型的值,打印它,并返回
Unit

例如,以下编译:

callFunc(printUnit)
正如这一点:

printUnit(callFunc(printUnit))
但不是这个:

callFunc(printUnit())
为什么??因为
callFunc
引用了一个签名为
Unit=>Unit
的函数,而
printUnit
满足了这个条件,所以编译器认为我们必须使用
对象。然后返回一个typ
Unit
,该值
printUnit
接受并打印

但是,如果我们在
printUnit
之后附加paren,我们会显式地调用它,返回
Unit
。因此第三个示例没有编译,因为
callFunc
只引用函数,它不接受类型为
Unit
的简单值

如果要显式引用编译器无法派生该意图的函数,可以使用:

但是,如果您明确说明了类型,编译器可以自己解决:

val f: () => Unit = loop

补充答案。除了括号外,Scala的行为方式与Python类似。比较以下两个示例:

//scala
def loop(): () => Unit = {
  println("function executed")
  loop _
}
scala> loop
function executed
res0: () => Unit = <function0>
scala> loop _
res1: () => () => Unit = <function0>

#python
def loop():
    print("function executed")
    return loop
>>> loop()
function executed
<function loop at 0x1090f07d0>
>>> loop
<function loop at 0x1090f07d0>
//scala
def loop():()=>单位={
println(“已执行的函数”)
环路_
}
scala>循环
执行的功能
res0:()=>单位=
scala>循环_
res1:()=>()=>单元=
#蟒蛇
def loop():
打印(“已执行的功能”)
回路
>>>循环()
执行的功能
>>>环路

不同之处在于,在Python中,您可以通过调用
loop()
、引用调用
loop
的函数来执行函数,在Scala中,您可以执行调用
loop()
loop
的函数,并引用调用
loop的函数来添加答案。除了括号外,Scala还可以