在方法返回类型上输入推理

当在方法中使用显式的return语句时,为什么Scala无法推断方法的返回类型?

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

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

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

在方法中使用return ,会引入另一个方法可能返回的语句。 这意味着Scala无法确定在找到它的位置return的类型。 相反,它必须继续到方法结束,然后合并所有出口点以推断它们的类型,然后返回到每个这些出口点并分配​​它们的类型。

这样做会增加编译器的复杂性并减慢编译速度,因为在使用return时不必指定返回类型。 另一方面,在目前的系统中,推理返回类型是从Scala已经使用的有限类型推断中免费推出的。

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


这会增加编译器(和语言)的复杂性。 在类似的事情上进行类型推断真的很怪异。 与任何类型的推论相关,当你有一个单一的表达式时,它会更好。 分散的返回语句有效地创建了很多隐含的分支,这些分支对统一非常粘性。 这不是特别困难,只是粘性。 例如:

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

我问你,编译器在这里推断出什么? 如果编译器使用显式的返回语句进行推理,它将需要为Any 。 事实上,许多带有显式返回语句的方法最终都会返回Any ,即使你没有偷偷摸摸地获得非本地回报。 就像我说的,粘性。

最重要的是,这不是应该鼓励的语言功能。 显式返回不会提高代码的清晰度,除非只有一个明确的返回,并且在函数的末尾。 如果您将代码路径视为有向图,原因很容易看出。 正如我之前所说的那样,分散的返回会产生大量的隐式分支,这会在图形上产生怪异的叶子,以及主体中的许多额外路径。 这只是时髦。 控制流,看看你的分支都是明确的(模式匹配或容易得多if表达式)和你的代码将变得更加实用,如果你不依赖于副作用的return报表产生价值。

所以,像斯卡拉其他几个“望而却步”的特点(如asInstanceOf而不是as ),语言的设计者们犯了一个深思熟虑的选择,使事情不太愉快。 这与它引入的复杂性结合在类型推断中,以及除了最有意思的情景之外的所有结果的实际无用性。 对于Scalac来说,尝试这种推理是没有意义的。

故事的道德:学习不要分散你的回报! 这是任何语言的好建议,而不仅仅是Scala。


鉴于此(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

......它似乎不是无意的。

链接地址: http://www.djcxy.com/p/66201.html

上一篇: Type inference on method return type

下一篇: Can't pip ,the command on mac , search packages in local path not on the net