我最近开始学习用Scala编程,到目前为止一直很有趣。我真的很喜欢在另一个函数中声明函数的能力,这似乎是直觉所要做的事情。
我对Scala的一个恼怒是,Scala在其函数中需要显式的返回类型。我觉得这阻碍了语言的表达。而且,很难用这个需求来编程。也许是因为我来自Javascript和Ruby舒适区。但是对于像Scala这样的语言,它将在一个应用程序中包含大量的连接函数,我无法想象我如何在头脑中头脑风暴,我所编写的特定函数应该在递归之后返回什么类型的递归。
这种对函数的显式返回类型声明的要求,不需要像Java和C++这样的语言来困扰我。Java和C++中的递归,当它们确实发生时,通常最多处理2到3个函数。从未有几个函数像Scala那样链接在一起。
所以我想我想知道为什么Scala应该要求函数具有显式返回类型,这是否有一个很好的理由?
发布于 2012-10-03 03:52:19
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兼容性的考虑,选择了前者而不是后者,而“更纯”静态类型化的功能语言大多是在设计时考虑了相反的选择。
https://softwareengineering.stackexchange.com/questions/167179
复制相似问题