2009-12-11 8 views
19

Angenommen, ich habe diese:Gibt es eine Möglichkeit zu steuern, welche implizite Konvertierung standardmäßig verwendet wird?

class String2(val x:String) { 
    def *(times:Int) : String = { 
     val builder = new StringBuilder() 
     for(i <- 0 until times) { 
      builder.append(x) 
     } 
     builder.toString() 
    } 
} 

jetzt, wenn ich diese implizite hinzu:

implicit def gimmeString2(y:String) = new String2(y) 

Ich werde einen Kompilierungsfehler, weil stringWrapper fügt auch diese implizit. Gibt es eine Möglichkeit, dem Compiler zu sagen: "Ignoriere andere implitits, benutze das", damit ich kein String2 Objekt instanziieren und daran arbeiten muss?

Ich gebe zu, der Beispielcode möglicherweise nicht am besten geeignet (für diese Frage), aber ich denke, es wird tun.

+0

Mögliche doppelte: http://stackoverflow.com/questions/1339148/avoiding-implicit-def-ambiguity-in-scala –

+0

Ich glaube nicht, dass es ein Duplikat. Der Autor dieser Frage wollte beide implicits behalten. Ich will nur eins. – Geo

+0

Es gibt eine sehr ähnliche, wenn nicht identische Methode zu den oben bereits in RichString. Wenn Sie möchten, dass Ihre Methode verwendet wird, können Sie möglicherweise die Methode import a.b. {c => _} verwenden, um c zu verbergen, wobei c der Name der impliziten Methode ist. –

Antwort

29

Scala 2.8 hat ein Priorisierungssystem für implicits hinzugefügt. Es ist in diesem SIP on the new Java arrays erläutert:

Wenn zwei verschiedene anwendbaren Alternativen einer überladenen Verfahren zu vergleichen oder eines impliziten, jede Methode für mit spezifischeren Argumente einen Punkt erhält, und ein weiterer Punkt in einer geeigneten Unterklasse definiert ist. Eine alternative „gewinnt“ über eine andere, wenn es eine größere Anzahl von Punkten in diesen beiden Vergleiche Abschluss

bekommt, dass wenn Alternativen haben identische Argumenttypen, die eine, die in einer Unterklasse gewinnt definiert ist. Daher glaube ich, dass Sie implicits erklären könnte wie folgt aussehen:

trait LowPriorityImplicits { 
    //lower priority conversions 
} 

object HighPriorityImplicits extends LowPriorityImplicits { 
    //higher-order ones here 
} 
Verwandte Themen