Oder wie kann man das versehentliche Entfernen von Duplikaten vermeiden, wenn ein Set
abgebildet wird?
Dies ist ein Fehler, den ich sehr oft mache. Sehen Sie sich den folgenden Code an:
%Vor% Die Funktion zählt die akkumulierte Größe aller enthaltenen Listen. Das Problem ist, dass nach dem Zuordnen der Listen zu ihren Längen das Ergebnis immer noch Set
ist und alle Listen der Größe 1 auf einen einzigen Repräsentanten reduziert sind.
Habe ich nur dieses Problem? Kann ich etwas dagegen tun? Ich denke, ich hätte gerne zwei Methoden mapToSet
und mapToSeq
für Set
. Aber es gibt keine Möglichkeit, dies zu erzwingen, und manchmal merkt man nicht lokal, dass man mit Set
arbeitet.
Vielleicht ist es sogar möglich, dass Sie Code für eine Seq
schreiben und etwas in einer anderen Klasse ändert und das zugrunde liegende Objekt wird zu einem Set
?
Vielleicht etwas wie eine Best Practice, um diese Situation gar nicht erst entstehen zu lassen?
Stellen Sie sich die folgende Situation vor:
%Vor% Sie holen eine Sammlung von Node
-Objekten aus einem Graphen, benutzen sie, um ihre benachbarten Kanten zu erhalten und summieren sich über ihnen. Dies funktioniert, wenn graph.nodes
eine Seq
zurückgibt.
Und es bricht, wenn jemand entscheidet, dass Graph
seine Knoten als Set
zurückgibt; ohne dass dieser Code verdächtig erscheint (zumindest nicht für mich, erwartest du, dass jede Sammlung am Ende ein Set
sein könnte?) und ohne ihn zu berühren.
Es scheint, dass es viele mögliche "Gotchas" geben wird, wenn man ein Seq
erwartet und ein Set
bekommt. Es ist keine Überraschung, dass Methodenimplementierungen vom Typ des Objekts und (mit Überladung) der Argumente abhängen können. Mit Scala implicits kann die Methode sogar vom erwarteten Rückgabetyp abhängen.
Eine Möglichkeit, sich gegen Überraschungen zu wehren, besteht darin, Typen explizit zu kennzeichnen. Beispielsweise Annotationsmethoden mit Rückgabetypen, auch wenn dies nicht erforderlich ist. Wenn der Typ von graph.nodes
von Seq
in Set
geändert wird, ist zumindest dem Programmierer bewusst, dass ein potenzieller Bruch vorliegt.
Warum definieren Sie nicht Ihre eigene Methode mapToSeq
,
Der Vorteil von breakOut: CanBuildFrom
besteht darin, dass die Konvertierung von Set
in Seq
keinen zusätzlichen Aufwand verursacht.
Sie können das Pimp My Library-Muster verwenden, damit mapToSeq
angezeigt wird Teil des Traversable
- Merkmals, geerbt von Seq
und Set
.
Tags und Links scala