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

私が見る方法は、暗黙的なパラメーター リストが通常のパラメーター リストを置き換えないということです。コンストラクター定義には少なくとも 1 つのパラメーター リストが必要であるため、何も明示的に指定されていない場合は '()' が生成されます。

これは確かに不可解かもしれませんが、パラメーター リストがまったく存在しない場合に空のコンストラクターを生成することと一致しています。

于 2010-07-12T10:44:21.067 に答える
5

さて、@venechkaの答えの助けを借りて、私はそれを理解したと思います.

通常のクラスでは、Scala は、クラス宣言 ( class B) またはクラスのインスタンス化の時点 (new Aおよび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 に答える