问题描述
Scala编译器通常可以推断方法的返回类型,但是在某些情况下需要指定返回类型.例如,递归方法要求指定返回类型.
The Scala compiler can often infer return types for methods, but there are some circumstances where it's required to specify the return type. Recursive methods, for example, require a return type to be specified.
我注意到有时我会收到错误消息重载的方法(方法名)需要返回类型",但这不是必须始终为重载的方法指定返回类型的一般规则(我有一些示例,但我没有得到错误).
I notice that sometimes I get the error message "overloaded method (methodname) requires return type", but it's not a general rule that return types must always be specified for overloaded methods (I have examples where I don't get this error).
对于一般方法,特别是对于重载方法,到底何时需要指定返回类型?
When exactly is it required to specify a return type, for methods in general and specifically for overloaded methods?
推荐答案
第2章.键入 Programming Scala 的少做多" > 图书提及:
The Chapter 2. Type Less, Do More of the Programming Scala book mentions:
实际上,对于以下情况,您必须提供显式类型注释:
In practical terms, you have to provide explicit type annotations for the following situations:
在以下情况下,方法返回值:
Method return values in the following cases:
- 当您显式调用return方法时(甚至在末尾).
- 方法是递归的.
- 当一个方法重载并且其中一个方法调用另一个方法时.调用方法需要一个返回类型注释.
- 当推断的返回类型比您预期的更通用时,例如
Any
.
- 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()
}
// 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")) )
如果运行此脚本,则会出现以下错误.
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, "")
def joiner(strings: List[String]): String = joiner(strings, " ")
基本上,即使Scala可以推断出返回类型也是一个好习惯.
Randall Schulz 注释:
请记住,如果让编译器推断方法的结果类型,则它可能比您想要的更为具体. (例如,用HashMap代替Map.)
并且由于您可能想在返回类型中公开最小接口(例如,请参见此),这种推断可能会妨碍您.
And since you may want to expose the minimal interface in your return type (see for instance this SO question), this kind of inference might get in the way.
关于最后一种情况(推断的返回类型将比您预期的更通用"),肯·布鲁姆添加:
And about the last scenario ("When the inferred return type would be more general than you intended"), Ken Bloom adds:
(触发比预期的返回类型更通用的错误代码是:
(The faulty code which triggers a "more general than expected return type was:
// 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,但Ken却把它叫出来了:
, which I incorrectly interpreted and List[Any] because returning an empty List, but Ken called it out:
这篇关于Scala中的方法何时需要返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!