2015-03-25 10 views
7

vedere il codice,Perché questa case class può contenere più parametri di quelli che dichiara?

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

mi definiscono un case class qui.

e quindi chiamare

Wrapped(1,2,2,4).

Con mia sorpresa, anche Wrapped(1,2,3,4,5) (qualsiasi numero di parametri) può funzionare senza errori di compilazione.

+0

L'istanza avvolta ha solo un singolo argomento - a 'Tuple4 [Int, Int, Int, Int]'. – Lee

risposta

12

Si chiama auto-tupling.

Il compilatore proverà a recuperare gli argomenti extra avvolgendoli tutti in una tupla.

Wrapped(1,2,3,4) 

viene trasformato automaticamente in

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

Tra l'altro, questa è una caratteristica fastidiosa e sorprendente e spero davvero che sarà alla fine deprecato. Nel frattempo ci sono due opzioni di compilazione disponibili:

  • -Ywarn-adapted-args, che mette in guardia in caso di autotupling
  • -Yno-adapted-args, che dà un errore nelle stesse circostanze

Esempio con avvertimento:

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

Esempio con errore:

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

Questa è davvero una strana "caratteristica" di cui non ero a conoscenza. – ziggystar

+0

"args adattati" è sinonimo di "autotuplicazione"? –

+0

È quello più l'inserimento automatico delle unità, che è già deprecato ora –

1

un'occhiata più da vicino al codice:

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

parametri vengono compattati in Tuple oggetto. Quindi hai Wrapped[(Int, Int, Int, Int, Int)] anziché il desiderato Wrapped[Int].

Problemi correlati