为什么这个案例类可以包含比它声明的更多的参数?

che*_*gpu 7 scala

看代码,

 case class Wrapped[A](elem: A)(implicit ordering: Ordering[A])
    extends Ordered[Wrapped[A]] {
    def compare(that: Wrapped[A]): Int = ordering.compare(this.elem, that.elem)
  }
Run Code Online (Sandbox Code Playgroud)

我在case class这里定义一个.

然后打电话

Wrapped(1,2,2,4).

令我惊讶的是,即使Wrapped(1,2,3,4,5)(任意数量的参数)也能正常工作而不会编译错误.

Gab*_*lla 14

它被称为自动元组.

编译器将尝试通过将所有参数包装在元组中来弥补额外的参数.

Wrapped(1,2,3,4)
Run Code Online (Sandbox Code Playgroud)

自动变成了

Wrapped((1,2,3,4))
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这是一个令人烦恼和令人惊讶的功能,我真的希望它最终会被弃用.同时,您有两个可用的编译器选项:

  • -Ywarn-adapted-args,在自动装配的情况下发出警告
  • -Yno-adapted-args,在相同的情况下给出错误

带警告的示例:

scala -Ywarn-adapted-args

scala> case class Foo[A](a: A)

scala> Foo(1, 2)
<console>:10: warning: Adapting argument list by creating a 2-tuple: this may not be what you want.
        signature: Foo.apply[A](a: A): Foo[A]
  given arguments: 1, 2
 after adaptation: Foo((1, 2): (Int, Int))
              Foo(1, 2)
                 ^
res1: Foo[(Int, Int)] = Foo((1,2))
Run Code Online (Sandbox Code Playgroud)

错误示例:

scala -Yno-adapted-args

scala> case class Foo[A](a: A)
defined class Foo

scala> Foo(1, 2)
<console>:10: warning: No automatic adaptation here: use explicit parentheses.
        signature: Foo.apply[A](a: A): Foo[A]
  given arguments: 1, 2
 after adaptation: Foo((1, 2): (Int, Int))
              Foo(1, 2)
                 ^
<console>:10: error: too many arguments for method apply: (a: (Int, Int))Foo[(Int, Int)] in object Foo
              Foo(1, 2)
                 ^
Run Code Online (Sandbox Code Playgroud)