Scala-style-guide建议在使用Unit
时始终显式定义返回类型expect:
应根据以下模式声明方法:
def foo(bar: Baz): Bin = expr
此规则的唯一例外是返回Unit的方法。这样 方法应该使用Scala的语法糖来避免意外 令人困惑的退货类型:
def foo(bar: Baz) { // return type is Unit expr }
答案 0 :(得分:1)
正如评论家指出的那样,Martin Odersky在链接的主题演讲中对此进行了讨论。当然,正如“什么时候......”所表明的那样,这最终是一个风格问题,所以人们只能发表意见。
两件事:(1)类型是/否,以及(2)程序语法是/否。
(1)显然,对于纯API(没有实现),您必须指定返回类型。我会将此扩展到任何方法实现,同时 API 。即,如果您的方法没有实现特征 - 在这种情况下编译器会在返回类型不同时给出错误 - 您应该注释该方法。 私有和本地方法可以推断出返回类型,除非您发现很难在第一眼看出类型,或者您被迫(例如在递归方法调用中)。还有人说,当你给出明确的返回类型时,编译是更快。
如果您使用“easy”返回类型的简短方法,我认为推理很好。实施例
trait Foo {
def sqrt(d: Double) = math.sqrt(d)
def toString = "Foo"
def bar = new Bar(123)
}
(但已经有人可能认为math.sqrt
可能不会显示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
,模式match
,synchronized
阻止或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
}
}