这个问题可能非常愚蠢,但我有点困惑,这是scala中最好的方法。 在scala中,编译器执行类型推断并为每个变量或方法分配最接近(或可能是限制)类型。 我是scala的新手,从许多示例代码/库中,我注意到在许多地方,人们大多数时间都没有明确地提供类型。但是,在我编写的大多数代码中,我/仍然明确提供类型。例如:
val someVal: String = "def"
def getMeResult() : List[String]= {
val list:List[String] = List("abc","def")
list
}
我开始编写这个特别是方法返回类型的原因是,当我自己编写一个方法时,我知道它应该返回什么。所以如果我明确提供了返回类型,我可以知道我是否犯了任何错误。此外,我觉得通过阅读返回类型本身更容易理解该方法返回的内容。否则,我将检查最后一个语句的返回类型。
所以我的疑问/怀疑是: 1.由于编译器不必推断很多,编译时间是否较少?或者它并不重要? 2.斯卡拉世界的正常标准是什么?
答案 0 :(得分:5)
来自“Scala in Depth”第4.5章:
对于人类阅读一个非常重要的方法实现,推断出 返回类型可能会令人不安。最好明确记录和 在公共API中强制执行返回类型。
来自“Programming in Scala”第2章:
有时Scala编译器会要求您指定结果 函数的类型。例如,如果函数是递归的,那么 必须明确指定函数的结果类型。
明确指出函数结果类型通常是个好主意。 这种类型的注释可以使代码更容易阅读,因为 读者无需研究功能体来弄清楚推断 结果类型。
来自“Scala in Action”第2.2.3节:
为用户指定返回类型是一个好习惯 图书馆。如果你认为从功能中不清楚它的回归是什么 type是,尝试改进名称或指定返回类型。
来自“Programming Scala”第1章:
递归函数是执行范围的一个例外 超出了正文的范围,所以返回类型必须是 声明。
对于简单的功能,也许展示它并不重要 明确。但是,有时推断的类型不会是什么 预期。显式返回类型提供了有用的文档 读者。我建议添加返回类型,尤其是在公共API中。
在以下情况下,您必须提供显式返回类型:
- 在方法中显式调用return时。
- 当一个方法递归时。
- 当两个或多个方法重载并且其中一个方法调用另一个方法时;调用方法需要返回类型注释。
- 当推断的返回类型比您预期的更为通用时,例如,Any。
答案 1 :(得分:4)
其他答案中尚未提及的另一个原因如下。你可能知道program to an interface, not an implementation是个好主意。
对于函数或方法的返回值,这意味着您不希望函数或方法的用户知道函数返回的某个接口(或特征)的具体实现 - 这是您想要的实现细节隐藏。
如果你写这样的方法:
trait Example
class ExampleImpl1 extends Example { ... }
class ExampleImpl2 extends Example { ... }
def example() = new ExampleImpl1
然后该方法的返回类型将被推断为ExampleImpl1
- 因此,它暴露了它返回特征Example
的特定实现的事实。您可以使用显式返回类型来隐藏它:
def example(): Example = new ExampleImpl1
答案 2 :(得分:2)
标准规则是使用API的显式类型(为了精确指定类型和防止重构)以及implicits(特别是因为如果定义站点位于后面,则可以忽略没有显式类型的implicits使用网站)。
对于第一个问题,类型推断可能是一个重要的税收,但这与写作和阅读表达的容易性相平衡。
在示例中,本地列表上的类型甚至不是“更好的java”。这只是视觉上的混乱。
但是,应该很容易阅读推断类型。偶尔,我必须启动IDE才能告诉我推断的内容。
通过暗示,方法应该足够短,以便于扫描结果类型。
很抱歉缺少参考资料。也许别人会挺身而出; MLs和SO上经常出现这个话题。
答案 3 :(得分:1)
尽可能使用类型推断,但首先要明确,并在公共API中支持显式。
您几乎不应该注释私有字段或局部变量的类型,因为它们的类型通常会在其值中立即显示出来:
private val name = "Daniel"
但是,您可能仍希望显示指定值具有复杂或非显而易见形式的类型。
所有公共方法都应该有明确的类型注释。在这些情况下,类型推断可能会破坏封装,因为它取决于内部方法和类详细信息。如果没有显式类型,对方法或val的内部的更改可能会在不发出警告的情况下更改类的公共API,从而可能破坏客户端代码。显式类型注释也有助于缩短编译时间。
twitter scala style guide说方法返回类型:
虽然Scala允许省略这些注释,但这样的注释提供了良好的文档:这对于公共方法尤其重要。如果方法没有暴露且返回类型明显,则省略它们。
我认为广泛的共识是显式类型应该用于公共API,并且不应该用于大多数局部变量声明。何时使用显式类型"内部"方法不那么明确,更多的是判断问题;不同的组织有不同的标准。
1。类型推断似乎并没有明显影响推理发生的行的编译时间(除了一些基本上是编译器错误的隐含的罕见情况) - 毕竟,编译器仍然需要检查类型,这是用来推断它的计算几乎相同。但是,如果推断出方法返回类型,那么当该方法发生更改时,必须重新编译使用该方法的任何内容。
因此,推断在许多地方使用的方法(或公共变量)会降低编译速度(特别是如果您使用增量编译)。但推断仅在一个或两个地方使用的本地或私人变量,私有方法或公共方法,不会产生(重大)差异。