Scala 编译器通常可以推断方法的返回类型,但在某些情况下需要指定返回类型。例如,递归方法需要指定返回类型。
我注意到有时我会收到错误消息“重载的方法(方法名)需要返回类型”,但这并不是一个一般规则,即必须始终为重载方法指定返回类型(我有一些我没有收到此错误的示例)。
什么时候需要指定返回类型,对于一般的方法,特别是对于重载的方法?
最佳答案
Chapter 2. Type Less, Do More的 Programming Scala 书中提到:
When Explicit Type Annotations Are Required.
In practical terms, you have to provide explicit type annotations for the following situations:
Method return values in the following cases:
- When you explicitly call return in a method (even at the end).
- When a method is recursive.
- When a method is overloaded and one of the methods calls another. The calling method needs a return type annotation.
- When the inferred return type would be more general than you intended, e.g.,
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()
}
Overloaded methods can sometimes require an explicit return type. When one such method calls another, we have to add a return type to the one doing the calling, as in this example.
// 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")) )
The two
joiner
methods concatenate aList
of strings together.
The first method also takes an argument for the separator string.
The second method calls the first with a “default” separator of a single space.If you run this script, you get the following error.
... 9: error: overloaded method joiner needs result type
def joiner(strings: List[String]) = joiner(strings, "")
Since the second
joiner
method calls the first, it requires an explicitString
return type. It should look like this:
def joiner(strings: List[String]): String = joiner(strings, " ")
基本上,指定返回类型可能是一个好习惯,即使 Scala 可以推断它 .
Randall Schulz评论:
As a matter of (my personal) style, I give explicit return types for all but the most simple methods (basically, one-liners with no conditional logic).
Keep in mind that if you let the compiler infer a method's result type, it may well be more specific than you want. (E.g., HashMap instead of Map.)
而且由于您可能希望在返回类型中公开最小接口(interface)(例如,参见 SO question ),这种推断可能会妨碍您。
关于最后一种情况(“当推断的返回类型比您预期的更一般时”),Ken Bloom补充说:
specify the return type when you want the compiler to verify that code in the function returns the type you expected
(触发“比预期更一般的返回类型”的错误代码是:
// 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
,我错误地解释和 List[Any] 因为返回一个空列表,但肯把它叫出来:
List(0)
doesn't create a list with 0 elements.
It creates aList[Int]
containing one element (the value 0).
Thus aList[Int]
on one conditional branch and aList[String]
on the other conditional branch generalize toList[Any]
.
In this case, the typer isn't being overly-general -- it's a bug in the code.
)
关于scala - Scala 中的方法何时需要返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3127208/