ret*_*nym 18 constructor scala implicit
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)
Run Code Online (Sandbox Code Playgroud)
为什么Scalac在类声明中提供的隐式参数列表之前插入一个空参数列表?
从scalac来源的评论来看,这似乎是一个特征,而不是一个错误:
//如果它是唯一的参数部分,则将(隐式...)转换为()(隐式...)
我很想知道为什么这样做.我觉得这很令人惊讶.
我看到它的方式是隐式参数列表不替换常规参数列表.因为对于构造函数定义,至少需要一个参数列表,如果没有明确指示,则生成'()'.
虽然这可能确实令人费解,但是当没有参数列表存在时,它与生成空构造函数一致.
好的,在@ 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
Run Code Online (Sandbox Code Playgroud)
因此,为了符合这个原则,它在隐式参数列表(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
Run Code Online (Sandbox Code Playgroud)