什么时候可以在 Scala 中安全地省略括号?

When can parentheses be safely omitted in Scala?

这是一个玩具示例:

object Example {

  import collection.mutable
  import collection.immutable.TreeSet

  val x = TreeSet(1, 5, 8, 12)
  val y = mutable.Set.empty ++= x
  val z = TreeSet.empty ++ y
  // This gives an error: unspecified parameter
  //  val z = TreeSet.empty() ++ y

}

显然 TreeSet.emptyTreeSet.empty() 不是一回事。幕后发生了什么?我什么时候可以安全地省略(或在这种情况下不省略)括号?


更新

我已经向控制台发送了一些代码,然后在评估上面的代码之前在 intellij 中将其删除,这里是:

  implicit object StringOrdering extends Ordering[String] {
    def compare(o1: String, o2: String) = {
      o1.length - o2.length
    }
  }
  object StringOrdering1 extends Ordering[String] {
    def compare(o1: String, o2: String) = {
      o2.length - o1.length
    }
  }

这是一个特例,与何时可以和不能省略括号不太相关。

这是TreeSet.empty的签名:

def empty[A](implicit ordering: Ordering[A]): TreeSet[A]

它有一个隐式参数列表,需要一个 Ordering 作为包含的类型 A。当您调用 TreeSet.empty 时,编译器将尝试隐式查找正确的 Ordering[A].

但是当你调用TreeSet.empty()时,编译器认为你试图显式提供隐式参数。除非你在列表中遗漏了参数,这是一个编译错误(错误的参数数量)。唯一可行的方法是显式传递一些 Ordering: TreeSet.empty(Ordering.Int).


旁注:您的上述代码实际上并未使用 TreeSet.empty 进行编译,因为它屈服于 Ordering 的模糊隐式错误。在您的范围内可能有一些隐含的 Ordering[Int] 您没有包含在问题中。最好使类型明确并使用 TreeSet.empty[Int].