可变的Collection.empty方法是否违反了Scala的零参数命名约定?

时间:2015-07-01 02:23:59

标签: scala collections naming-conventions side-effects

This是如何在Scala 11.5中的.empty对象中声明scala.collection.mutable.Map方法:

def empty[A, B]: Map[A, B]

这个方法不应该有空括号,像这样吗?

def empty[A, B](): Map[A, B]

Scala的naming conventions页面建议,在没有明确说明的情况下,省略0-arity方法的括号是纯函数代码的约定,包括空括号意味着该方法有副作用。 (我想我已经遇到了一条更明确的错误信息。)

可变.empty方法有副作用,因为您可以将单独调用的结果区分为.empty。它不应该是空括号,即使它在immutable.Map中的配偶没有?

关于我自己的代码,在从0-arity方法创建和返回可变对象时,我应该遵循一个特殊的命名约定吗?

2 个答案:

答案 0 :(得分:6)

没有。 scala.collection.mutable.Map.empty[A, B]没有任何副作用。这是一种每次调用时都会返回新mutable.Map[A, B]的方法。

mutable.Map#empty(特征本身中的方法)也返回相同类型的新空mutable.Map。它不会清空集合(就像它似乎可能),因此没有副作用。

如果您不确定,请参阅the source

答案 1 :(得分:1)

JVM上有点混乱。

在存在像eq / ne和System.identityHashCode这样的操作的情况下,即使创建一个新的 不可变的 对象也会产生可观察到的副作用(即增加一些反击JVM的大小使得下一个对象将具有不同的引用hashCode)。所以在JVM领域,除了返回一个新对象之外什么都不做的功能被认为是副作用,因为你可以获得。如果返回的对象是可变的,那么参考透明度无论如何都会离开窗口,即使生成可变对象本身的函数被认为是无副作用的。

如果你真的很迂腐,那么JVM上的 没有 副作用免费函数会返回非基元。

scala> import scala.collection.immutable._
scala> SortedSet.empty[Int] eq SortedSet.empty[Int]
res4: Boolean = false