2010-12-18 5 views
2

Irgendwelche Ideen, warum funktioniert das folgende nicht?scala: pimp meine Bibliothek mit Überladungen

implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs) 
class ListExtensions[A](xs : List[A]) 
{ 
    def foreach[B](f: (A, Int) => B) 
    { 
     var i = 0; 
     for (el <- xs) 
     { 
      f(el, i); 
      i += 1; 
     } 
    } 
} 

var a = List(1, 2, 3); 
a foreach { (el, i) => println(el, i) }; 

Als ich das kompilieren mit fsc 2.8.1, bekomme ich folgende Fehlermeldung: „falsche Anzahl von Parametern; expected = 1: eine foreach {(el, i) => println (el, i)} ". Mache ich etwas falsch oder gibt es einfach keine Möglichkeit, eine überladene Methode mit dem Trick "pimp my library" hinzuzufügen?

P.S. Ich frage mich nicht, ob ich die iterate-with-current-index-Variante von foreach implementieren soll (ich kenne die zipWithIndex-Methode), sondern vielmehr, wie Überladung und implizite Konvertierungen zusammenspielen.

+0

möglich Duplikat [Aufschalten arithmetischen Operatoren auf Int über implizite Konvertierungen] foreachWithIndex (http://stackoverflow.com/questions/4443783/overriding-arithmetic-operators-on -int-via-implizite-Konvertierungen –

Antwort

10

Der Compiler versucht nie, die implizite Konvertierung zu verwenden, da es bereits eine foreach-Methode für List gibt. Genauer gesagt besagt Abschnitt 7.3 der Scala Language Specification (http://www.scala-lang.org/docu/files/ScalaReference.pdf), dass eine implizite Konvertierung in zwei Fällen angewendet wird, wobei der zweite Fall für das Beispiel relevant ist :

In a selection e.m with e of type T, if the selector m does not denote a member of T.

Als Nebenwirkung, können Sie eine foreach mit einem Index unter Verwendung der zipWithIndex Methode erreichen.

1

Implizite Konvertierung tritt nur ein, wenn Sie versuchen, eine Methode zu verwenden, die nicht im Quelltyp vorhanden ist.

In diesem Fall verfügt List über eine foreach-Methode, sodass keine Konvertierung in Betracht gezogen wird. Sie erhalten jedoch einen Fehler, wenn die erwartete Signatur nicht übereinstimmt.

1
(a : ListExtensions[Int]) foreach { (el, i) => println(el, i) }; 

Oder den Namen ändern

Verwandte Themen