Scala中的方法何时需要返回类型? [英] When is a return type required for methods in Scala?

查看:293
本文介绍了Scala中的方法何时需要返回类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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()
}

重载的方法有时可能需要显式的返回类型.当一个这样的方法调用另一个方法时,我们必须在执行该调用的方法上添加一个返回类型,如本例所示.

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")) )

这两个joiner方法将一个字符串的List连接在一起.
第一个方法还为分隔符字符串使用一个参数.
第二种方法使用第一个带有单个空格的默认"分隔符来调用第一个方法.

The two joiner methods concatenate a List 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, "")

由于第二个joiner方法调用第一个方法,因此它需要显式的String返回类型.它应该看起来像这样:

Since the second joiner method calls the first, it requires an explicit String 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).

请记住,如果让编译器推断方法的结果类型,则它可能比您想要的更为具体. (例如,用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:

List(0)不会创建具有0个元素的列表.
它创建一个包含一个元素(值0)的List[Int].
因此,一个条件分支上的List[Int]和另一条件分支上的List[String]泛化为List[Any].
在这种情况下,打字机不是过于笼统-这是代码中的错误.
)

List(0) doesn't create a list with 0 elements.
It creates a List[Int] containing one element (the value 0).
Thus a List[Int] on one conditional branch and a List[String] on the other conditional branch generalize to List[Any].
In this case, the typer isn't being overly-general -- it's a bug in the code.
)

这篇关于Scala中的方法何时需要返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆