Frage

Ich habe mich gefragt, ob transparent implicit Umwandlungen sind wirklich so eine gute Idee ist und ob es vielleicht sogar besser sein implicits mehr zu verwenden, um, explizit . Angenommen, ich habe eine Methode, die ein Date als Parameter akzeptiert, und ich habe eine implizite Konvertierung, die eine String in eine Date verwandelt:

implicit def str2date(s: String) : Date = new SimpleDateFormat("yyyyMMdd").parse(s)

private def foo(d: Date)

Dann natürlich kann ich nenne dies mit einer transparenten implicit Umwandlung:

foo("20090910")

Wäre es besser, die Tatsache zu machen, dass ich die Zeichenfolge in ein Datum an Umwandlung expliziten?

class DateString(val s: String) { 
  def toDate : Date = new SimpleDateFormat("yyyyMMdd").parse(s) 
}

implicit def str2datestr(s: String) : DateString = new DateString(s)

So wird die Nutzung sieht eher aus wie:

foo("20090910".toDate)

Der Vorteil hierbei ist, dass es klarer später, was passiert - ich habe ein paar Mal jetzt durch transparente implicit Konvertierungen ertappt ich wissen sollte und diese Nutzung noch erlaubt uns (Option jemand Iterable?) nutzen Sie die Kraft des implicits.

War es hilfreich?

Lösung

in Bezug auf die Lesbarkeit viel besser ist als die vollständig transparent ein, zumindest in diesem Beispiel

Ich glaube, die mehr „explicit“ Art und Weise implizite Konvertierungen zu tun.

Meiner Meinung nach, implicit geben As vollständig transparent vom Typ B mit OK ist, wenn Sie können immer ein Objekt vom Typ A anzuzeigen in der Lage, verwendet werden, wann immer und Objekt vom Typ B benötigt wird . Zum Beispiel macht die implizite Umwandlung eines String zu einem RandomAccessSeq[Char] immer Sinne - ein String immer kann konzeptionell als eine Folge von Zeichen betrachtet wird (in C, ist eine Zeichenfolge nur eine Folge von Zeichen, zum Beispiel). Ein Aufruf von x.foreach(println) macht Sinn für alle Strings.

Auf der anderen Seite, die mehr expliziten Konvertierungen sollten verwendet werden, wenn ein Objekt vom Typ A kann manchmal als ein Objekt vom Typ B verwendet werden. In Ihrem Beispiel wird ein Aufruf an foo("bar") nicht Sinn und wirft einen Fehler. Wie Scala nicht geprüfte Ausnahmen hat, ein Anruf eindeutig foo(s.toDate) signalisiert, dass es möglicherweise eine Ausnahme ausgelöst werden (s vielleicht kein gültiges Datum sein). Auch sieht foo("bar".toDate) eindeutig falsch, während Sie Dokumentation konsultieren müssen, um zu sehen, warum foo("bar") könnte falsch sein. Ein Beispiel hierfür in der Scala-Standardbibliothek ist Konvertierungen von Strings zu Ints über die toInt Methode des RichString Wrapper (Strings als Ints zu sehen, aber nicht die ganze Zeit ).

Andere Tipps

Wenn Sie eine implizite Konvertierung von X nach Y machen (wie die Umwandlung von String zu Datum oben), sind Sie im Wesentlichen das zu sagen, Sie hatte die volle Kontrolle über Schrift X in erster Linie hätten, würden Sie gemacht haben X zu implementieren oder sein eine Unterklasse von Y.

Wenn es Sinn macht, für X-Y zu implementieren, dann die Konvertierung hinzuzufügen. Wenn dies nicht der Fall, dann ist es vielleicht nicht angemessen. Zum Beispiel macht es Sinn, für String RandomAccessSeq [Char], zu implementieren, aber vielleicht macht es keinen Sinn macht für String Datum zu implementieren (obwohl String Umsetzung StringDate scheint in Ordnung).

(Ich bin ein wenig zu spät, und Flaviu hat eine ausgezeichnete Antwort, aber ich wollte einen Kommentar hinzufügen, wie ich denke, über implicits.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top