2012-08-13 10 views
13

Ich dachte, die korrekte Verwendung der neuen impliziten Klassen von Scala 2.10 würde:So verwenden Scala 2.10 implizite Klassen

implicit case class IntOps(i: Int) extends AnyVal { 
    def twice = i * 2 
} 

11.twice 

Offensichtlich nicht:

<console>:13: error: value twice is not a member of Int 
       11.twice 
       ^

Bin ich etwas fehle (Scala 2.10 .0-M6)?

+3

Dies ist ein Fehler. Ich öffnete [SI-6227] (https://issues.scala-lang.org/browse/SI-6227), obwohl es mich nicht überraschen würde zu entdecken, dass es ein Duplikat ist. –

+0

Eine 'implizite Klasse' kann keine' Fallklasse' sein, das ist der einzige Grund. – Valerin

Antwort

21

Ein Hinweis der Entzuckern impliziter Klassen ist, erklärt in the SIP-13:

implicit class RichInt(n: Int) extends Ordered[Int] { 
def min(m: Int): Int = if (n <= m) n else m 
... 
} 

wird vom Compiler wie folgt transformiert werden:

class RichInt(n: Int) extends Ordered[Int] { 
def min(m: Int): Int = if (n <= m) n else m 
... 
} 
implicit final def RichInt(n: Int): RichInt = new RichInt(n) 

Wie Sie sehen können, hat die implizite Funktion, die erstellt wird, den gleichen Namen wie die ursprünglichen Klassen. Ich denke, es ist so gemacht, damit implizite Klassen leichter importiert werden können.

So in Ihrem Fall, wenn Sie eine implizite Fall Klasse erstellen, gibt es einen Konflikt zwischen dem Methodennamen durch das implicit Schlüsselwort und das Begleitobjekt erstellt durch das case Schlüsselwort erstellt.

+0

Ok, das macht Sinn, danke –

+0

Für mich sieht das eher wie ein Bug aus. 'case' erzeugt eine' apply' Methode, implizit eine Methode mit dem Namen der Klasse. – soc

+0

@Nicolas Entschuldigung für Fragen nach 3+ Jahren. Aber ich würde mich freuen, wenn Sie zeigen können, wie Sie den entzuckerten Code erhalten. Danke – Polymerase

2

Dies zeigt, gibt es eine Mehrdeutigkeit:

val ops: IntOps = 11 

<console>:11: error: ambiguous reference to overloaded definition, 
both method IntOps of type (i: Int)IntOps 
and object IntOps of type IntOps.type 
match argument types (Int) and expected result type IntOps 
     val ops: IntOps = 11 
         ^

nicht sicher, was genau passiert. Aber wenn kein case class mit es scheint in Ordnung:

implicit class IntOps(val i: Int) extends AnyVal { 
    def twice = i * 2 
} 

11.twice // ok