有括号方法和无括号方法区别

在 scala 中,如果方法不接受参数,如:

def foo(): String = "foo"

那么我们定义时可以省去括号:

def foo: String = "foo"

这两个方法调用效果是等价的,即:

scala> foo()
res0: String = foo

等价于

scala> foo
res1: String = foo

但是它们定义上不等价,比如我们可以定义如下两个类以及一个结构类型(以下实验基于 scala 2.12.4):

class A {
  def foo(): String = "foo"
}

class B {
  def foo: String = "foo"
}

type fooType = {
  def foo: String
}
val a = new A()
val b = new B()

然后定义一个接受 fooType 类型的函数:

def fun(fooCls: fooType): Unit =
  println(fooCls.foo)

调用

fun(b) 

将成功输出 foo;但是调用

fun(a) 

则产生错误

type mismatch;
 found   : A$A6.this.a.type (with underlying type A$A6.this.A)
 required: A$A6.this.fooType
    (which expands to)  AnyRef{def foo: String}
fun(a);}
    ^

另一方面,如果我们定义结构类型为:

type fooType = {
  def foo(): String
}

那么这时调用 fun(b) 成功,但是调用 fun(a) 失败。

这不是一个 Bug,可参考 [1] 中的评论。编译器将区分 foo() 和 foo,认为这是两个不同类型的函数。

参考

  1. Structural Types: Multiple Methods and Type Aliasing

Previous post: Scala implicit

Next post: Scala implicitly