Scala - correspondência de padrões
A correspondência de padrões é o segundo recurso mais amplamente usado do Scala, depois dos valores de função e fechamentos. Scala fornece um excelente suporte para correspondência de padrões no processamento de mensagens.
Uma correspondência de padrão inclui uma sequência de alternativas, cada uma começando com a palavra-chave case. Cada alternativa inclui umpattern e um ou mais expressions, que será avaliado se o padrão corresponder. Um símbolo de seta => separa o padrão das expressões.
Experimente o programa de exemplo a seguir, que mostra como comparar com um valor inteiro.
Exemplo
object Demo {
def main(args: Array[String]) {
println(matchTest(3))
}
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
}
Salve o programa acima em Demo.scala. Os seguintes comandos são usados para compilar e executar este programa.
Comando
\>scalac Demo.scala
\>scala Demo
Resultado
many
O bloco com as instruções case define uma função, que mapeia inteiros para strings. A palavra-chave match fornece uma maneira conveniente de aplicar uma função (como a função de correspondência de padrões acima) a um objeto.
Experimente o programa de exemplo a seguir, que compara um valor com padrões de diferentes tipos.
Exemplo
object Demo {
def main(args: Array[String]) {
println(matchTest("two"))
println(matchTest("test"))
println(matchTest(1))
}
def matchTest(x: Any): Any = x match {
case 1 => "one"
case "two" => 2
case y: Int => "scala.Int"
case _ => "many"
}
}
Salve o programa acima em Demo.scala. Os seguintes comandos são usados para compilar e executar este programa.
Comando
\>scalac Demo.scala
\>scala Demo
Resultado
2
many
one
Combinando usando classes de caso
o case classessão classes especiais usadas na correspondência de padrões com expressões de caso. Sintaticamente, essas são classes padrão com um modificador especial:case.
Tente o seguinte, é um exemplo simples de correspondência de padrões usando a classe de caso.
Exemplo
object Demo {
def main(args: Array[String]) {
val alice = new Person("Alice", 25)
val bob = new Person("Bob", 32)
val charlie = new Person("Charlie", 32)
for (person <- List(alice, bob, charlie)) {
person match {
case Person("Alice", 25) => println("Hi Alice!")
case Person("Bob", 32) => println("Hi Bob!")
case Person(name, age) => println(
"Age: " + age + " year, name: " + name + "?")
}
}
}
case class Person(name: String, age: Int)
}
Salve o programa acima em Demo.scala. Os seguintes comandos são usados para compilar e executar este programa.
Comando
\>scalac Demo.scala
\>scala Demo
Resultado
Hi Alice!
Hi Bob!
Age: 32 year, name: Charlie?
Adicionar a palavra-chave case faz com que o compilador adicione vários recursos úteis automaticamente. A palavra-chave sugere uma associação com expressões de caso na correspondência de padrões.
Primeiro, o compilador converte automaticamente os argumentos do construtor em campos imutáveis (vals). A palavra-chave val é opcional. Se você quiser campos mutáveis, use a palavra-chave var. Portanto, nossas listas de argumentos do construtor agora são mais curtas.
Em segundo lugar, o compilador implementa automaticamente equals, hashCode, e toStringmétodos para a classe, que usam os campos especificados como argumentos do construtor. Portanto, não precisamos mais de nossos próprios métodos toString ().
Finalmente, também, o corpo de Person a classe fica vazia porque não há métodos que precisemos definir!