Wie wandle ich eine Variable in Scala um?

199

GraphicsWie kann ich eine Variable mit Typ Graphics2Din Scala umwandeln?

Eugene Yokota
quelle

Antworten:

282

Die bevorzugte Technik ist die Verwendung des Mustervergleichs. Auf diese Weise können Sie den Fall, dass der betreffende Wert nicht vom angegebenen Typ ist, ordnungsgemäß behandeln :

g match {
  case g2: Graphics2D => g2
  case _ => throw new ClassCastException
}

Dieser Block repliziert die Semantik der asInstanceOf[Graphics2D]Methode, jedoch mit größerer Flexibilität. Sie können beispielsweise verschiedene Zweige für verschiedene Typen bereitstellen und so mehrere bedingte Casts gleichzeitig ausführen. Schließlich müssen Sie nicht wirklich brauchen eine Ausnahme in der catch-all - Bereich zu werfen, können Sie auch zurückkehren null(oder bevorzugt None), oder Sie könnten einige Ausweich Zweig, der ohne funktioniert eingeben Graphics2D.

Kurz gesagt, das ist wirklich der richtige Weg. Es ist etwas syntaktisch sperriger als asInstanceOf, aber die zusätzliche Flexibilität lohnt sich fast immer.

Daniel Spiewak
quelle
19
+1 weil es interessant ist, aber ein bisschen zu viel für dieses Szenario. ist es nicht?
Eugene Yokota
Was ist, wenn ich bereits ein Muster gefunden habe, aber den Verweis auf den gegossenen Wert verloren habe: <code> base match {case MyConcrete (value) => base.asInstanceOf [MyConcrete] .something (value)} </ code>, gibt es eine Möglichkeit, ' base 'in MyConcrete umgewandelt, auch wenn Sie "value" extrahieren möchten, indem Sie den von "case MyConcrete (value)" ausgeführten Aufruf "unapply" ausnutzen?
Ithkuil
4
Versuchen Sie Folgendes: Das base match { case base @ MyConcrete(value) => base.something(value) } Abschatten baseist natürlich optional. Sie können genauso gut einen anderen Variablennamen verwenden.
Daniel Spiewak
Was ich nicht verstehe, ist, wie würden Sie das Ergebnis dieses Mustervergleichs in eine Variable umwandeln? wie in Java, wenn es String a = (String) b war; Was wäre das Scala-Äquivalent?
James McMahon
@ JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Kevin Meredith
224
g.asInstanceOf[Graphics2D];
Eugene Yokota
quelle
36
Als ich mich an Scala asInstanceOfgewöhnt hatte , lernte ich, es nicht zu benutzen , da es den Zweck eines statischen Typsystems zunichte macht und sich glücklich anfühlt.
Eugene Yokota
26
Leider ist dies eine häufige Operation bei der Verwendung von Swing. Für benutzerdefinierte Malvorgänge müssen Sie die Methode 'public void paintComponent (Graphics g)' überschreiben. Der Graphics-Parameter ist eigentlich eine Graphics2D-Instanz, es ist jedoch eine Umwandlung erforderlich. Die Pattern Matching-Version ist wahrscheinlich ausführlicher als gerechtfertigt. Denken Sie daran: Vermeiden Sie verschleierte Hyperverbosität und Prolixität!
Hohonuuli
7
@hohonuuli Ich denke, die Besetzung ist in diesem speziellen Fall in Ordnung, aber wenn Sie scala-swingKomponenten verwenden, ist der Parameter von paintComponent bereits Graphics2D, so dass keine Besetzung erforderlich ist
Luigi Plinge
2
Warum ist es so lang? Warum "asInstanceOf wann kann nur" als "oder" asof "Schlüsselwort oder Methode sein? Oder warum haben sie nicht einfach die C ++ - und Java-Methode als Option übernommen, weil dies die konventionelle ist und es kein großes Problem damit gibt?
LEMUEL ADANE
16
@LemuelAdane Die Tatsache, dass Sie überhaupt Casts verwenden, ist ein Codegeruch. Es macht keinen Sinn, sie einfacher zu machen.
Daenyth