18
scala> class A(implicit a: Int);
defined class A

scala> class B()(implicit a: Int);
defined class B

scala> new A()(1)
res1: A = A@159d450

scala> new B()(1)
res2: B = B@171f735

scala> new A(1)
<console>:7: error: too many arguments for constructor A: ()(implicit a: Int)A
       new A(1)

为什么Scalac会在类声明中提供的隐式参数列表之前插入一个空参数列表?

从 scalac 来源中的评论来看,这似乎是一个功能,而不是一个错误:

// 如果它是唯一的参数部分,则将 (implicit ... ) 转换为 ()(implicit ... )

我很想知道为什么会这样做。我觉得相当令人惊讶。

4

2 回答 2

7

我看到它的方式是隐式参数列表不会取代常规参数列表。因为对于构造函数定义,至少需要一个参数列表,如果没有明确指示,则生成“()”。

虽然这可能确实令人费解,但它与在不存在任何参数列表时生成空构造函数是一致的。

于 2010-07-12T10:44:21.067 回答
5

好的,在@venechka 的回答的帮助下,我想我已经弄清楚了。

对于普通类,Scala 会在类声明 ( class B) 或类实例化点 ( new Aand new B) 进行推断和空参数列表:

scala> class A()
defined class A

scala> new A
res19: A = A@12cdd20

scala> new A()
res20: A = A@1c37b8f

scala> class B
defined class B

scala> new B
res21: B = B@12801c5

scala> new B()
res22: B = B@79a340

所以为了符合这个原则,它在隐式参数列表(class D(implicit ...))之前推断出一个空参数列表。

scala> class C()(implicit a: Int = 0)
defined class C

scala> new C
res23: C = C@9d1714

scala> new C()
res24: C = C@b38dba

scala> new C()(0)
res25: C = C@1677979

scala> class D(implicit a: Int = 0)
defined class D

scala> new D
res26: D = D@1a0d111

scala> new D()
res27: D = D@14e3372

scala> new D()(0)
res28: D = D@1609872
于 2010-07-12T11:20:59.233 回答