Como faço para converter uma variável no Scala?

199

Dada uma variável com o tipo Graphics, como a transmito Graphics2Dno Scala?

Eugene Yokota
fonte

Respostas:

282

A técnica preferida é usar a correspondência de padrões. Isso permite que você lide com o caso de que o valor em questão não seja do tipo especificado:

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

Este bloco replica a semântica do asInstanceOf[Graphics2D]método, mas com maior flexibilidade. Por exemplo, você pode fornecer ramificações diferentes para vários tipos, executando efetivamente várias transmissões condicionais ao mesmo tempo. Por fim, você realmente não precisa lançar uma exceção na área catch-all, também pode retornar null(ou preferencialmente None) ou inserir um ramo de fallback que funcione sem Graphics2D.

Em suma, este é realmente o caminho a percorrer. É um pouco mais sintaticamente volumoso do que asInstanceOf, mas a flexibilidade adicional quase sempre vale a pena.

Daniel Spiewak
fonte
19
+1 porque é interessante, mas um pouco demais para esse cenário. não é?
Eugene Yokota
e se eu já tiver correspondido o padrão, mas perder a referência ao valor convertido: <code> base match {case MyConcrete (value) => base.asInstanceOf [MyConcrete] .algo (valor)} </code>, existe uma maneira de obter ' base 'convertida para MyConcrete, mesmo que você queira extrair "valor", explorando a chamada' não aplicar 'realizada por "case MyConcrete (value)"?
Ithkuil
4
Tente o seguinte: base match { case base @ MyConcrete(value) => base.something(value) } obviamente, a sombra baseé opcional. Você poderia facilmente usar um nome de variável diferente.
Daniel Spiewak
O que eu não entendo é como você obteria o resultado dessa correspondência de padrão convertida em uma variável? como em java se fosse String a = (String) b; qual seria o equivalente da scala?
James McMahon
@JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Kevin Meredith
224
g.asInstanceOf[Graphics2D];
Eugene Yokota
fonte
36
Depois que me acostumei com o Scala, aprendi a não usá- asInstanceOflo, uma vez que isso derrota o propósito de ter um sistema de tipo estático e parece nojento.
Eugene Yokota
26
Infelizmente, essa é uma operação comum ao usar o Swing. Para operações de pintura personalizadas, você precisa substituir o método 'public void paintComponent (Graphics g)'. O parâmetro Graphics é na verdade uma instância Graphics2D, mas uma conversão é necessária. A versão de correspondência de padrões é provavelmente mais detalhada do que a necessária. Lembre-se: Evite com sedução a hiperverbosidade e a prolixação ofuscantes!
hohonuuli
7
@hohonuuli Eu acho que o elenco é bom, nesse caso específico, mas se você usar scala-swingcomponentes, o parâmetro de paintComponent já está Graphics2D de modo nenhum o lançarei necessário
Luigi Plinge
2
Por que é tanto tempo? Por que "asInstanceOf quando pode ser apenas" as "ou" asof "palavra-chave ou método? Ou por que eles não adotaram apenas a maneira C ++ e Java como uma opção, porque esse é o convencional e não há grande problema com isso?
LEMUEL ADANE
16
@LemuelAdane O fato de você estar usando transmissões é um cheiro de código, não faz sentido torná-las mais fáceis.
Daenyth