Estou fazendo correspondência com algumas classes de caso e gostaria de tratar dois dos casos da mesma maneira. Algo assim:
abstract class Foo
case class A extends Foo
case class B(s:String) extends Foo
case class C(s:String) extends Foo
def matcher(l: Foo): String = {
l match {
case A() => "A"
case B(sb) | C(sc) => "B"
case _ => "default"
}
}
Mas quando faço isso, recebo o erro:
(fragment of test.scala):10: error: illegal variable in pattern alternative
case B(sb) | C(sc) => "B"
Posso fazê-lo funcionar removendo os parâmetros da definição de B e C, mas como posso combinar com os parâmetros?
scala
pattern-matching
Timdisney
fonte
fonte
case A(x) | B(x) => println(x)
permitido onde o tipo dex
é definido como o limite superior no sistema de tipos de tudo o que A (x) e B (x) produzem.Existem algumas maneiras que posso ver de alcançar o que você procura, se houver alguma semelhança entre as classes de caso. O primeiro é fazer com que as classes de caso estendam um traço que declara a comunalidade, o segundo é usar um tipo estrutural que remove a necessidade de estender suas classes de caso.
O método do tipo estrutural gera um aviso de apagamento que, no momento, não tenho certeza de como eliminar.
fonte
Bem, isso realmente não faz sentido, não é? B e C são mutuamente exclusivos, então sb ou sc são vinculados, mas você não sabe quais, então você precisaria de mais lógica de seleção para decidir qual usar (dado que eles foram vinculados a uma Option [String], não uma linha). Portanto, não há nada a ganhar com isso:
Ou isto:
fonte
args match { case Array("-x", hostArg) => (hostArg, true); case Array(hostArg, "-x") => (hostArg, true) }
No entanto, vejo que esse não é o caso comum e que criar um método local é uma alternativa. No entanto, se a alternativa for conveniente, não há sentido em ter alternativas de caso. Na verdade, em alguns dialetos de ML você tem um recurso semelhante e ainda pode vincular variáveis, desde que (IIRC) cada variável seja vinculada ao mesmo tipo em ambas as alternativas.