Come faccio a trasmettere una variabile in Scala?


199

Data una variabile con tipo Graphics, come posso eseguirne il cast Graphics2Din Scala?

Risposte:


282

La tecnica preferita è usare la corrispondenza del modello. Ciò consente di gestire con garbo il caso in cui il valore in questione non sia del tipo specificato:

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

Questo blocco replica la semantica del asInstanceOf[Graphics2D]metodo, ma con una maggiore flessibilità. Ad esempio, potresti fornire diversi rami per vari tipi, eseguendo efficacemente più cast condizionali contemporaneamente. Infine, non hai davvero bisogno di lanciare un'eccezione nell'area catch-all, potresti anche tornare null(o preferibilmente, None) o potresti entrare in qualche ramo di fallback che funziona senza Graphics2D.

In breve, questa è davvero la strada da percorrere. È un po 'più sintatticamente ingombrante di asInstanceOf, ma ne vale quasi sempre la flessibilità aggiuntiva.


19
+1 perché è interessante, ma un po 'troppo per questo scenario. non è vero?
Eugene Yokota,

cosa succede se ho già modellato ma ho perso il riferimento al valore castato: <code> base match {case MyConcrete (value) => base.asInstanceOf [MyConcrete] .something (value)} </code>, c'è un modo per ottenere ' base 'trasmesso a MyConcrete anche se si desidera estrarre "valore" sfruttando la chiamata "non applicabile" eseguita da "case MyConcrete (valore)"?
ithkuil,

4
Prova questo: base match { case base @ MyConcrete(value) => base.something(value) } ovviamente l'ombreggiatura baseè facoltativa. Potresti usare altrettanto facilmente un nome di variabile diverso.
Daniel Spiewak,

Quello che non capisco è come otterresti il ​​risultato di questo cast di pattern matching in una variabile? come in java se fosse String a = (String) b; quale sarebbe lo scala equivalente?
James McMahon,

@JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Kevin Meredith,

224
g.asInstanceOf[Graphics2D];

36
Una volta mi sono abituato a Scala, ho imparato a non usarlo asInstanceOf, dal momento che sconfigge lo scopo di avere un sistema di tipo statico e mi sento fortunato.
Eugene Yokota,

26
Sfortunatamente, questa è un'operazione comune quando si utilizza Swing. Per operazioni di verniciatura personalizzate, è necessario sovrascrivere il metodo "public void paintComponent (Graphics g)". Il parametro Graphics è in realtà un'istanza Graphics2D, ma è necessario un cast. La versione di corrispondenza del modello è probabilmente più verbosità che giustificata. Ricorda: evitare seducentemente l'iperverbosità e la prolissità offuscate!
Hohonuuli,

7
@hohonuuli Penso che il cast vada bene in quel caso specifico, ma se usi i scala-swingcomponenti, il parametro di paintComponent è già Graphics2D, quindi nessun cast richiesto
Luigi Plinge,

2
Perché è così lungo? Perché "asInstanceOf quando può essere solo" come "o" asof "parola chiave o metodo? O perché non hanno semplicemente adottato il modo C ++ e Java come opzione perché è convenzionale e non c'è nessun grosso problema con quello?
LEMUEL ADANE,

16
@LemuelAdane Il fatto che tu stia usando i cast è un odore di codice, non ha senso renderli più facili.
Daenyth,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.