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方法创建和返回可变对象时,我应该遵循一个特殊的命名约定吗?
答案 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