所以我一直试图通过各种方式来解决你在Scala中定义东西的方法,因为我对 {}
块的处理方式缺乏了解而变得复杂:
object NewMain extends Thing{
def f1 = 10
def f2 {10}
def f3 = {10}
def f4() = 10
def f5() {10}
def f6() = {10}
def f7 = () => 10
def f8 = () => {10}
def f9 = {() => {10}}
def main(args: Array[String]){
println(f1) // 10
println(f2) // ()
println(f3) // 10
println(f4) // 10
println(f4()) // 10
println(f5) // ()
println(f5()) // ()
println(f6) // 10
println(f6()) // 10
println(f7) // <function0>
println(f7()) // 10
println(f8) // <function0>
println(f8()) // 10
println(f9) // <function0>
println(f9()) // 10
}
}
据推测,其中一些是等价的,其中一些是其他人的语法糖,有些是我不应该使用的东西,但我不能为我的生活弄明白 . 我的具体问题是:
-
println(f2)
和println(f5())
如何给出unit
?这不是块10
中的最后一项吗?它与println(f3())
有什么不同,它给出了10
? -
如果
println(f5)
给unit
,println(f5())
不应该无效,因为unit
不是函数?这同样适用于println(f6)
和println(f6())
-
在所有打印10:
f1
,f3
,f4
,f4()
,f6
,f6()
,f7()
,f8()
,f9()
中,它们之间是否有任何功能差异(就其作用而言)或使用差异(就何时而言)我应该用哪个)?或者它们都相同?
4 回答
按顺序回答您的问题:
f2
和f5()
返回Unit
因为scala将任何def
没有“=
”作为返回Unit
的函数,无论块中的最后一项是什么 . 这是一件好事,因为否则定义一个不返回任何东西的函数就不会相当冗长 .println(f5())
有效,即使它返回Unit
因为在scala中Unit
是一个有效的对象,但不可否认,你可以实例化它 . 例如,Unit.toString()
是有效的,如果不是通常有用的语句 .并非所有打印出来的版本_1566336都是相同的 . 最重要的是,
f7
,f8
和f9
实际上是返回返回10
的函数的函数,而不是直接返回10
. 当您声明def f8 = () => {10}
时,您声明一个不带参数的函数f8
并返回一个不带参数的函数并返回一个整数 . 当你调用println(f8)
然后f8
dilligently返回该功能给你 . 当你调用println(f8())
它返回函数,然后立即调用它 .函数
f1
,f3
,f4
和f6
在它们的作用方面基本上是等价的,它们仅在样式方面有所不同 .正如“用户未知”所示,大括号仅对于作用范围很重要,并且不会对您的用例产生任何影响 .
是的sytactic糖
因此,如果省略“=”,该方法将始终返回Unit类型的对象 . 在Scala中,方法和表达式总是返回一些东西 .
如果你写def f()=()=> 10,它与写入相同
这意味着f正在返回一个函数对象 . 但是你可以写
当你使用f()调用它时,它返回10个Function对象,并且在大多数情况下可以交换使用方法,但是存在一些语法差异 . 例如当你写作
你得到“10”,但是当你写作
你得到
另一方面,当你有这个
println都会打印相同的东西
在预期函数对象的位置使用方法的名称并且方法签名与预期函数对象的签名匹配时,它将自动转换 . 所以
list.map(inc)
会被scala编译器自动转换为六年后,未来Scala的版本将在未来发布,事情有所改善:
已删除定义
f2
和f5
为“procedure syntax”能够在没有parens has been removed的情况下调用
f4
f5
和f6
.这带来了我们定义一个函数的9种方法,以及将它们调用为7种定义函数的方法和10种调用它们的方法:
另见lampepfl/dotty2570 lampepfl/dotty#2571
因此,相对清楚哪种语法是可选的(例如
{}
s)以及哪些定义是等效的(例如def f4() = 10
和def f7 = () => 10
) . 希望有一天,当Dotty / Scala-3.0发布时,学习该语言的新手将不再面对我六年前所做的混乱 .第二种形式不使用作业 . 因此,您可以将其视为一个程序 . 这并不意味着回归然后返回Unit,即使最后一个语句可以用来返回特定的东西(但它可能是一个if语句,只能在一个分支中有特定的东西) .
你这里不需要括号 . 例如,如果定义了val,则需要它们,因此该val的范围仅限于封闭块 .
你需要花括号来定义val sqr . 如果val在内部分支中声明,则花括号不需要位于方法的顶级:
为了进一步研究,当两个方法返回相同的结果时,您可以编译它们并比较字节码 . 两个二进制相同的方法将是相同的 .