这个
Chapter 2. Type Less, Do More
的
Programming Scala
书中提到:
实际上,您必须为以下情况提供显式类型注释:
方法在以下情况下返回值:
-
在方法中显式调用return时(即使在最后)。
-
当一个方法是递归的。
-
当一个方法重载并且其中一个方法调用另一个方法时。调用方法需要返回类型注释。
-
Any
.
例子:
// code-examples/TypeLessDoMore/method-nested-return-script.scala
// ERROR: Won't compile until you put a String return type on upCase.
def upCase(s: String) = {
if (s.length == 0)
return s // ERROR - forces return type of upCase to be declared.
else
s.toUpperCase()
}
// code-examples/TypeLessDoMore/method-overloaded-return-script.scala
// Version 1 of "StringUtil" (with a compilation error).
// ERROR: Won't compile: needs a String return type on the second "joiner".
object StringUtil {
def joiner(strings: List[String], separator: String): String =
strings.mkString(separator)
def joiner(strings: List[String]) = joiner(strings, " ") // ERROR
}
import StringUtil._ // Import the joiner methods.
println( joiner(List("Programming", "Scala")) )
joiner
方法连接
List
一串串串在一起。
第二个方法使用单个空格的默认分隔符调用第一个方法。
如果运行此脚本,将出现以下错误。
... 9: error: overloaded method joiner needs result type
def joiner(strings: List[String]) = joiner(strings, "")
从第二天开始
细木工
方法调用第一个,它需要显式
String
返回类型。应该是这样的:
def joiner(strings: List[String]): String = joiner(strings, " ")
指定返回类型是一种很好的做法,即使Scala可以推断它
.
Randall Schulz
评论:
作为(我个人)风格的问题,除了最简单的方法(基本上,没有条件逻辑的一行程序)之外,我为所有方法提供显式返回类型。
由于您可能希望在返回类型中公开最小接口(例如,请参见下面的示例)
SO question
),这种推断可能会妨碍。
关于最后一个场景(“当推断的返回类型比您预期的更一般时”),
Ken Bloom
添加:
当您希望编译器验证函数中的代码是否返回预期的类型时,请指定返回类型
// code-examples/TypeLessDoMore/method-broad-inference-return-script.scala
// ERROR: Won't compile. Method actually returns List[Any], which is too "broad".
def makeList(strings: String*) = {
if (strings.length == 0)
List(0) // #1
else
strings.toList
}
val list: List[String] = makeList() // ERROR
,我错误地解释并列出了[Any],因为返回了一个空列表,但Ken说:
List(0)
它创造了一个
List[Int]
因此
列表
List[String]
另一个条件分支推广到
List[Any]
.
在这种情况下,
.
)