什么时候在Scala方法声明中使用等号?


85

等号:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
  }
}

没有等号:

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello!")
  }
}

以上两个程序都以相同的方式执行。在博客文章《我不喜欢Scala》中,我读到缺少等号时,该方法将返回Unit(与Java相同void),因此返回值的方法必须使用等号。但是不返回值的方法可以用任何一种方式编写。

在Scala方法中使用不返回值的等号的最佳实践是什么?

Answers:


108

我实际上非常不同意Daniel。我认为不相等的语法应该永远不会被使用。如果您的方法作为API公开,并且您担心意外返回错误的类型,请添加显式类型注释:

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello!")
    123
  }
}

非相等语法较短,可能看起来更“干净”,但我认为这只会增加混淆的可能性。有时我忘记加了一个等号,并认为我的方法实际上是在返回Unit时返回一个值。由于非相等和推断类型的语法在视觉上是如此相似,因此很容易遗漏此问题。

即使花了我更多的工作,我还是更喜欢显式类型注释(当它们很重要时)(即公开的接口)。


1
我喜欢这种方法,它对读者来说更加明确,因此更加清晰。
Lukasz Korzybski 2012年

4
显然现在是推荐的样式(docs.scala-lang.org/style/declarations.html#procedure_syntax),因此我将其更改为可接受的答案。
Esko Luontola 2014年

1
我也同意这一点,我认为不带=的语法应该从语言中完全删除
Ahmed Soliman Farghal 2014年

7
马丁·奥德斯基(Martin Odersky)在他的主题演讲“斯卡拉风格”中说,这是历史上的错误。他必须添加此语法(不带=),以便他可以对Java开发人员隐藏“ Unit”,以免引起混淆。他还提到将来会删除它。
Radian 2014年

2
如果方法定义中忘记了等号,是否有警告的方法?例如,作为编译器选项还是在任何源分析工具中?
VasiliNovikov 2014年

42

更新:从Scala-2.10开始,首选使用等号。旧答案:

返回的方法Unit始终使用非等于语法。这样可以避免在执行过程中潜在的错误,这些错误会延续到API中。例如,您可能不小心做了这样的事情:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
    123
  }
}

当然是简单的例子,但是您可以看到这可能是一个问题。由于最后一个表达式并没有返回Unit,该方法本身具有比其他返回类型Unit。这在公共API中公开,并且可能会导致其他问题。使用非等于语法,最后一个表达式是什么都没关系,Scala将返回类型固定为Unit

这也是两个字符更清洁。:-)我也倾向于认为非相等语法使代码更易于阅读。显然,所讨论的方法返回Unit而不是某些有用的值。

在相关说明中,抽象方法有一个类似的语法:

trait Foo {
  def bar(s: String)
}

该方法bar具有签名String=>Unit。当您在抽象成员上省略类型注释时,Scala会这样做。再次,这更干净,而且(我认为)更容易阅读。


3
不使用等号也是Scala的风格指南中的建议:davetron5000.github.com/scala-style/types/inference/...
艾司科Luontola

6
我写了一点,所以在权衡参考文献时,您可能应该记住这一点。:-)
丹尼尔·斯皮沃克

大声笑,所以我向我的女友描述了这一次小小的交流,除了由于我的口齿不清外,“位”以“ b子”的形式出现了。不用说,随之而来的喜剧。
Saem 2010年

10
ScalaDays 2013,Martin Odersky,主题演讲-具有样式第45章的Scala:应避免过程声明(非相等语法)。
senia


12

必须在调用声明中使用等号,但返回Unit的定义除外。

在后一种情况下,您可以放弃等号。不过,可能不建议使用此语法,因此最好避免使用。使用等号并声明返回类型将始终有效。


书籍,邮件列表,源代码。顺便说一句,从那时起,很明显后一种语法不太可能被弃用,并且被许多人所青睐。
Daniel C. Sobral

1
docs.scala-lang.org/style/types.html#function_values看起来样式指南始终指示使用=的类型。
BeepDog 2014年

4

对于方法,《Scala风格指南》建议使用equals语法而不是过程语法

程序语法

避免使用过程语法,因为它可能会因简短性增加而造成混淆。

// don't do this
def printBar(bar: Baz) {
  println(bar)
}
// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}

0

一件事:假设应该返回Unit的方法的最后一个语句不返回Unit。那么使用非相等语法非常方便,我希望这不会被弃用,因为我看到了几个用例


0

随着时间的流逝,默认样式已更改,并且在答案的许多注释中都提到了默认样式,建议在官方样式指南中将=语法用于函数声明。


1
您提供的链接仅讨论函数,而不是过程(即返回Unit的函数)。
Esko Luontola 2014年

您是对的,@ EskoLuontola,很抱歉,我可能从打开的多个标签之一中复制了错误的链接,该链接已更新。
BeepDog

0

对于没有返回值的方法,表达这种方法的一种方法是在结果后留一个大括号,将结果类型和等号排除在外。在这种形式下,该方法看起来像一个过程,仅出于副作用而执行该方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.