为什么Scala要求函数具有显式的返回类型?


11

我最近开始学习在Scala编程,到目前为止,它很有趣。我真的很喜欢在另一个函数中声明函数的功能,这似乎很直观。

关于Scala的一个烦恼是,Scala在其函数中需要显式的返回类型。而且我觉得这阻碍了语言的表达能力。同样,很难用该要求进行编程。也许是因为我来自Javascript和Ruby舒适区。但是对于像Scala这样在应用程序中具有成千上万个连接函数的语言,我无法想象如何头脑风暴,确切地讲出我正在编写的特定函数应该在递归之后返回的类型。

对于函数的显式返回类型声明的这种要求,对于像Java和C ++这样的语言,请不要打扰我。Java和C ++中的递归发生时,通常最多要处理2到3个函数。从来没有像Scala这样将多个功能链接在一起。

因此,我想我想知道是否有充分的理由解释为什么Scala应该要求具有显式返回类型的函数?


5
事实并非如此,而且我不明白为什么这样做会成为问题。
基思·汤普森

1
我以为是。在Scala中,函数的返回类型实际上是不明确的吗?
2012年

Answers:


15

Scala不需要所有函数都具有显式的返回类型,而只需递归函数即可。这样做的原因是,Scala的类型推断算法从头到尾都是(接近)简单的扫描,无法进行超前查找。

这意味着这样的功能:

def fortuneCookieJoke(message: String) = message + " in bed."

不需要返回类型,因为Scala编译器可以清楚地看到返回类型必须为,而无需使用逻辑变量或查看方法的参数以外的任何内容String

另一方面,这样的函数:

def mapInts(f: (Int) => Int, l: List[Int]) = l match {
  case Nil => Nil
  case x :: xs => f(x) :: mapInts(f, xs)
}

会导致编译时错误,因为Scala编译器在不使用前瞻或逻辑变量的情况下无法看到确切的类型mapInts。如果足够聪明,它最多可以说返回类型是的超类型List[Nothing],因为Nil该类型是。这样就无法在足够的信息附近准确地确定的返回类型mapInts

请注意,这是特定于Scala的,还有其他静态类型化的语言(大多数Miranda / Haskell / Clean系列,大多数ML系列以及其他一些分散的类型)都使用了更全面,更强大的类型推断算法。比Scala所用。另外,请注意,这并不完全是Scala的错。名义子类型化和整个模块类型推断从根本上是相互矛盾的,Scala的设计者出于Java兼容性的考虑选择了前者而不是后者,而“更纯”的静态类型函数语言主要是通过相反的选择。


4
实际上,问题不在于找出更全面的类型推断算法。它正在寻找一种更全面的类型推断算法,同时在当前的Scala编译器中保持高质量的错误消息
约尔格W¯¯米塔格

1
正确的回报case Nil实际上不是空List[Int]()吗?在这种情况下,足够聪明的编译器可以解决问题。我想这全是在扮演魔鬼的拥护者。
KChaloux 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.