2015-03-25 10 views
7

Zobacz koduDlaczego ta klasa przypadku może przechowywać więcej parametrów niż deklaruje?

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) 
    } 

I zdefiniować case class tutaj.

a następnie zadzwonić

Wrapped(1,2,2,4).

Ku mojemu zaskoczeniu, nawet Wrapped(1,2,3,4,5) (dowolna liczba parametrów) może działać poprawnie bez kompilacji błędu.

+0

Twoja opakowana instancja ma tylko jeden argument - 'Tuple4 [Int, Int, Int, Int]'. – Lee

Odpowiedz

12

To się nazywa auto-tupling.

Kompilator spróbuje nadrobić dodatkowe argumenty, zawijając je wszystkie w krotkę.

Wrapped(1,2,3,4) 

zostanie automatycznie przekształcony

Wrapped((1,2,3,4)) 

Nawiasem mówiąc, jest to denerwujące i zaskakująca funkcja i mam nadzieję, że w końcu będą przestarzałe. W międzyczasie masz dwie opcje kompilatora dostępny:

  • -Ywarn-adapted-args, który ostrzega w przypadku autotupling
  • -Yno-adapted-args, że daje błąd w tych samych okolicznościach

Przykład z ostrzeżeniem:

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)) 

Przykład z błędem:

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) 
       ^
+0

To naprawdę dziwna "cecha", o której nie wiedziałem. – ziggystar

+0

Czy "dostosowany argument" jest równoznaczny z "autotuplingiem"? –

+0

To jest plus automatyczne wstawianie jednostek, które już jest przestarzałe teraz –

1

Spójrz bliżej kodzie:

Wrapped(1,2,3,4,5) 
res0: Wrapped[(Int, Int, Int, Int, Int)] = Wrapped((1,2,3,4,5)) 

Parametry są sprasowane Tuple obiektu. Więc masz Wrapped[(Int, Int, Int, Int, Int)] zamiast pożądanego Wrapped[Int].

Powiązane problemy