11 Stimmen

Wie sollte ich Impliziten in meiner Scala-Anwendung organisieren?

Nachdem ich einige Scala-Tools geschrieben habe, versuche ich, die beste Möglichkeit zu finden, meinen Code zu organisieren - insbesondere die impliziten Elemente. Ich habe 2 Ziele:

  • Manchmal möchte ich nur die expliziten Elemente importieren, die ich benötige.
  • Manchmal möchte ich einfach alles importieren.

Um das Duplizieren der impliziten Elemente zu vermeiden, habe ich diese Struktur entwickelt (ähnlich wie die Art und Weise, wie scalaz aufgebaut ist):

case class StringW(s : String) {
  def contrived = s + "?"
}

trait StringWImplicits {
  implicit def To(s : String) = StringW(s)
  implicit def From(sw : StringW) = sw.s
}

object StringW extends StringWImplicits

// An anderer Stelle auf Monkey Island

object World extends StringWImplicits with ListWImplicits with MoreImplicits

Dies ermöglicht mir einfach

import StringW._ // Selektiver Import

oder (in den meisten Fällen)

import World._. // Importiere alles

Wie machen es die anderen?

4voto

oxbow_lakes Punkte 131223

Ich denke, dass implizite Konvertierungen gefährlich sind, wenn man nicht weiß, woher sie kommen. In meinem Fall platziere ich meine impliziten in einer Conversions-Klasse und importiere sie so nah wie möglich an der Verwendung.

def someMethod(d: Date) ; Unit {
  import mydate.Conversions._
  val tz = TimeZone.getDefault 
  val timeOfDay = d.getTimeOfDay(tz) //implizit hier verwendet
  ...
}

Ich bin mir nicht sicher, ob ich es mag, Implizites von verschiedenen traits "zu erben", aus demselben Grund, warum es als schlechte Java-Praxis angesehen wurde, ein interface zu implementieren, um seine Konstanten direkt zu verwenden (statische Imports werden stattdessen bevorzugt).

1voto

Flaviu Cipcigan Punkte 7153

Ich hatte normalerweise implizite Konvertierungen in einem Objekt, das deutlich signalisiert, dass das Importierte eine implizite Konvertierung ist.

Zum Beispiel, wenn ich eine Klasse com.foo.bar.FilthyRichString habe, würden die impliziten Konvertierungen in com.foo.bar.implicit.FilthyRichStringImplicit gehen. Ich weiß, die Namen sind etwas lang, aber deshalb haben wir IDEs (und die Scala-IDE-Unterstützung wird immer besser). Auf diese Weise finde ich es wichtig, dass alle impliziten Konvertierungen in einer 10-Sekunden-Codeprüfung deutlich sichtbar sind. Ich könnte den folgenden Code betrachten:

// andere Imports
import com.foo.bar.FilthyRichString

import com.foo.bar.util.Logger
import com.foo.bar.util.FileIO

import com.foo.bar.implicits.FilthyRichStringImplicit._
import com.foo.bar.implicits.MyListImplicit._
// andere Implizite

und auf einen Blick alle aktiven impliziten Konvertierungen in dieser Quelldatei sehen. Sie wären auch alle zusammengefasst, wenn Sie die Konvention verwenden, dass Importe nach Paketen gruppiert sind, mit einer neuen Zeile zwischen verschiedenen Paketen.

Entlang der gleichen Argumentation würde mir auch keine Sammelobjekt gefallen, das alle impliziten Konvertierungen enthält. In einem großen Projekt würden Sie wirklich alle impliziten Konvertierungen in all Ihren Quelldateien verwenden? Ich denke, dass dies eine sehr enge Kopplung zwischen verschiedenen Teilen Ihres Codes bedeutet.

Außerdem ist ein Sammelobjekt nicht für die Dokumentation sehr gut. Wenn Sie. Falls Sie alle verwendeten impliziten Konvertierungen in einer Datei explizit angeben, können Sie einfach Ihre Importanweisungen betrachten und sofort zur Dokumentation der impliziten Klasse springen. Bei einem Sammelobjekt müsste man das Objekt betrachten (was in einem großen Projekt riesig sein könnte) und dann nach der gewünschten impliziten Konvertierung suchen.

Ich stimme oxbow_lakes zu, dass das Vorhandensein impliziter Konvertierungen in traits schlecht ist, aufgrund der Versuchung, davon zu erben, was, wie er sagte, schlechte Praxis ist. Entlang dieser Linien würde ich die Objekte, die die impliziten Konvertierungen halten, grundsätzlich als final markieren, um der Versuchung vollständig zu entgehen. Seine Idee, sie so nah wie möglich an die Verwendung heranzuführen, ist ebenfalls sehr schön, wenn implizite Konvertierungen im Code nur sparsam verwendet werden.

-- Flaviu Cipcigan

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X