4

Scala-style-guide 建议在使用时始终明确定义返回类型 expect Unit

方法应根据以下模式声明:

def foo(bar: Baz): Bin = expr

此规则的唯一例外是返回 Unit 的方法。此类方法应使用 Scala 的语法糖以避免意外混淆返回类型:

def foo(bar: Baz) { // return type is Unit
  expr
}
4

1 回答 1

2

正如评论员所指出的,Martin Odersky 在链接的主题演讲中讨论了这一点。当然,正如“何时应该......”所表明的,这最终是一个文体问题,所以只能给出一个意见。

两件事:(1)类型是/否,以及(2)过程语法是/否。


(1) 显然,对于纯 API(没有实现),您必须指定返回类型。我会将其扩展到同时也是API的任何方法实现。即,如果你的方法没有实现一个特征——在这种情况下,当你的返回类型不同时编译器会给你一个错误——你应该注释这个方法。私有和本地方法都可以推断返回类型,除非您发现乍一看很难确定类型,或者您被迫(例如在递归方法调用中)。也有人说,当你给出明确的返回类型时,编译会更快。

如果您有具有“简单”返回类型的简短方法,我认为推理很好。前任。

trait Foo {
  def sqrt(d: Double) = math.sqrt(d)

  def toString = "Foo"

  def bar = new Bar(123)
}

(但已经有人可能争辩说math.sqrt返回 a可能并不明显Double)。

虽然更冗长,但您可以使代码更具可读性,并且避免 (a)在超类型足够的情况下泄漏有关实现或子类型的信息:

trait Before {
  def bar = new BarImpl

  def seq = Vector(1, 2, 3)
}

trait After {
  def bar: Bar = new BarImpl

  def seq: IndexedSeq[Int] = Vector(1, 2, 3)
}

并且(b)您避免意外返回您不打算返回的东西,从结构类型到错误的集合类型等。


(2) 直到最近我更喜欢过程语法,但在重新讨论和许多人表达了他们的不满之后,我尝试使用显式: Unit =注释,现在我更喜欢它了。我认为过程语法清楚地表明方法具有副作用,但确实: Unit =也很清楚地表明了这一点。它还经常删除花括号的数量:

trait Before {
  private var _x = 0
  def x: Int = _x
  def x_=(value: Int) { _x = value }
}

相对

trait After {
  private var _x = 0
  def x: Int = _x
  def x_=(value: Int): Unit = _x = value  // if double = confuses you, use new line?
}

我发现很多情况下正文以if、模式matchsynchronized块或future生成、集合map表达式等开头,在这些情况下删除花括号很好:

trait Before {
  def connect()(implicit tx: Tx) {
    values.foreach { case (x, _) =>
      x.changed += this
    }
  }
}

trait After {
  def connect()(implicit tx: Tx): Unit =
    values.foreach { case (x, _) =>
      x.changed += this
    }
}
于 2013-08-04T22:10:54.543 回答