何时在Scala方法声明中使用等号?

Esk*_*ola 84 scala

等号:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
  }
}
Run Code Online (Sandbox Code Playgroud)

没有等号:

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello!")
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Jor*_*tiz 105

我实际上与丹尼尔强烈反对.我认为永远不应该使用不相等的语法.如果您的方法作为API公开,并且您担心意外返回错误的类型,请添加显式类型注释:

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

不相等的语法更短,可能看起来"更干净",但我认为这只会增加混淆的可能性.我有时忘记添加一个等号,并且相信我的方法在返回Unit时返回了一个值.因为非等同和相等推断类型的语法在视觉上是相似的,所以很容易错过这个问题.

即使它花费了我更多的工作,我更喜欢显式类型注释(即暴露的接口).

  • Martin Odersky在他的主题演讲"Scala with Style"中说这是一个历史错误.他必须添加这种语法(没有=),以便他可以隐藏Java开发人员的"单位",这样他们就不会感到困惑.他还提到它将来会被删除. (7认同)
  • 显然现在是推荐的风格(http://docs.scala-lang.org/style/declarations.html#procedure_syntax)所以我将其改为接受的答案. (4认同)
  • 如果在方法定义中忘记了等号,是否有任何方法可以使用WARN?例如,作为编译器选项,还是在任何源分析工具中? (2认同)

Dan*_*wak 41

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

返回的方法Unit始终使用非等于语法.这避免了实施中携带到API的潜在错误.例如,您可能意外地做了类似这样的事情:

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

当然,这是一个简单的例子,但你可以看到这可能是一个问题.因为最后一个表达式没有返回Unit,所以方法本身将具有除以外的返回类型Unit.这在公共API中公开,并可能导致其他问题.使用非等于语法,最后一个表达式是什么并不重要,Scala将返回类型修复为Unit.

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

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

trait Foo {
  def bar(s: String)
}
Run Code Online (Sandbox Code Playgroud)

该方法bar具有签名String=>Unit.当您在抽象成员上省略类型注释时,Scala会执行此操作.再次,这是更清洁,(我认为)更容易阅读.

  • ScalaDays 2013,Martin Odersky,[Keynote - Scala with Style第45章](http://www.parleys.com/play/51c1994ae4b0d38b54f4621b/chapter45/about):应避免使用过程声明(非等于语法). (10认同)
  • 我写了那么一点,所以你在衡量参考时应该记住这一点.:-) (6认同)
  • 官方风格指南不再推荐这个:http://docs.scala-lang.org/style/declarations.html#procedure_syntax (4认同)
  • 不使用等号也是Scala风格指南中的建议:http://davetron5000.github.com/scala-style/types/inference/void_methods.html (3认同)

Dan*_*ral 12

除返回Unit的定义外,您必须使用等号登录调用声明.

在后一种情况下,您可以放弃等号.但是,这种语法可能已被弃用,因此最好避免使用.使用等号并声明返回类型将始终有效.