代码之家  ›  专栏  ›  技术社区  ›  Jesper

Scala中的方法何时需要返回类型?

  •  11
  • Jesper  · 技术社区  · 14 年前

    我注意到,有时会收到错误消息“overloaded method(methodname)requires return type”,但必须始终为重载方法指定返回类型并不是一般规则(我有一些示例没有收到此错误)。

    1 回复  |  直到 14 年前
        1
  •  20
  •   Community SushiHangover    7 年前

    这个 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] .
    在这种情况下, .
    )