代码之家  ›  专栏  ›  技术社区  ›  missingfaktor Kevin Wright

方法返回类型的类型推断

  •  27
  • missingfaktor Kevin Wright  · 技术社区  · 15 年前

    为什么Scala在有显式表达式的情况下无法推断方法的返回类型 return 方法中使用的语句?

    例如,为什么要编译下面的代码?

    object Main {
        def who = 5
        def main(args: Array[String]) = println(who)
    }
    

    object Main {
        def who = return 5
        def main(args: Array[String]) = println(who)
    }
    
    4 回复  |  直到 11 年前
        1
  •  30
  •   Daniel C. Sobral    15 年前

    方法的返回类型可以是定义它的块中最后一条语句的类型,也可以是在没有块的情况下定义它的表达式的类型。

    当你使用 return 在方法内部,引入另一条语句,该方法可以从中返回。这意味着Scala无法确定其类型 返回 在这一点上,它被发现了。相反,它必须一直进行到方法结束,然后合并所有出口点以推断其类型,然后返回到每个出口点并分配其类型。

    返回

    因此,最终,在编译器复杂性和获得的收益之间的平衡中,后者被认为不值得前者。

        2
  •  11
  •   Robert Harvey    13 年前

    这将增加编译器(和语言)的复杂性。对这样的事情进行类型推断真的很有趣。与任何与类型推断相关的操作一样,只有一个表达式时,所有操作都会更好。分散的返回语句有效地创建了许多隐式分支,这些分支很难统一。并不是说它特别重要 坚硬的 ,只是黏糊糊的。例如:

    def foo(xs: List[Int]) = xs map { i => return i; i }
    

    我问你,编译器在这里推断了什么?如果编译器使用显式返回语句进行推理,则需要 Any . 事实上,很多带有显式return语句的方法最终都会返回 ,即使你没有偷偷摸摸地得到非本地回报。就像我说的,黏糊糊的。

    提高代码的清晰度,除非函数末尾只有一个显式返回。如果将代码路径视为有向图,那么很容易看出原因。正如我前面所说的,分散的回报会产生很多隐式分支,这些分支会在图中产生奇怪的叶子,在主体中也会产生很多额外的路径。只是有点怪。如果分支都是显式的(模式匹配或 if 表达式),如果您不依赖于副作用,那么您的代码将更具功能性 return

    因此,就像Scala中其他几个“不受欢迎”的特性一样(例如。 asInstanceOf 而不是 as ),语言的设计者做出了深思熟虑的选择 令人愉快的这与它引入类型推断的复杂性以及结果在除最人为的场景外的所有场景中的实际无用性相结合。scalac尝试这种推断是没有任何意义的。

        3
  •  1
  •   Randall Schulz    15 年前

    鉴于此(2.8.Beta1):

    object Main {
      def who = return 5
      def main(args: Array[String]) = println(who)
    }
    <console>:5: error: method who has return statement; needs result type
             def who = return 5
    

    …这似乎不是疏忽。

        4
  •  -2
  •   Geoff Reedy    15 年前

    return 声明:)