Extracteurs:
Il existe deux méthodes utilisées pour les essoreuses, unapply
et unapplySeq
. Ils sont utilisés dans plusieurs affectations de variables et correspondances de modèles.
Le premier cas d'utilisation est où unapply prend l'objet qu'il est censé correspondre et retourne un Boolean
en fonction de si oui ou non elle correspond, par exemple,
trait Gender
trait Male extends Gender
trait Female extends Gender
object Male extends Male
object Female extends Female
class Person(val g: Gender, val age: Int)
object Adult {
def unapply(p: Person) = p.age >= 18
}
def check(p: Person) = p match {
case Adult() => println("An Adult")
case _ => println("A Child")
}
//Will print: An Adult since Adult.unapply returns true.
check(new Person(Female, 18))
//Will print: A Child as it falls through to the _ case.
check(new Person(Male, 17))
Honnêtement, je N'a pas vraiment le but de la syntaxe ci-dessus, car il peut être fait presque aussi simplement en mettant le code dans les instructions case
. Bien sûr, si vous avez un meilleur exemple, laisser un commentaire ci-dessous
Le cas général où unapply
prend un certain nombre d'actions fixe de paramètres et retourne soit un Option[T]
pour un seul paramètre ou un Option[(p1,p2,...)]
pour plusieurs, soit un tuple avec les valeurs reconnues, par exemple, continue à partir du code ci-dessus:
object Person {
def apply(g: Gender, age: Int) = new Person(g, age)
def unapply(p: Person) = if(p.age < 0) None else Some((p.g, p.age))
}
//Using Person.apply as described in the Basics section
val alice = Person(Female, 30)
val bob = Person(Male, 25)
//This calls Person.unapply(alice), which returns Some((Female, 30)).
//alice_gender is assigned Female and alice_age 30.
val Person(alice_gender, alice_age) = alice
bob match {
//Calls Person.unapply(bob), but sees that g is Male, so no match.
case Person(Female, _) => println("Hello ma'am")
//Calls Person.unapply(bob) and assigns age = bob.age, but it doesn't pass
//the 'if' statement, so it doesn't match here either.
case Person(Male, age) if age < 18 => println("Hey dude")
//So bob falls through to here
case _ => println("Hello Sir")
}
Person(Male,-1) match {
//Person.unapply(Person.apply(Male,-1)) returns None because p.age < 0.
//Therefore this case will not match.
case Person(_, _) => println("Hello person")
//Thus it falls through to here.
case _ => println("Are you Human?")
}
note:Case classes font tous ceux apply
/unapply
définitions pour vous (ainsi que d'autres choses), utilisez-les dès que possible pour gagner du temps et réduire le code.
unapplySeq
. Cela fonctionne de manière similaire à unapply
comme ci-dessus, sauf qu'il doit retourner un Option
d'une sorte de séquence.
Comme un exemple rapide,
scala> List.unapplySeq(List(1,2,3))
res2: Some[List[Int]] = Some(List(1, 2, 3))
Plus de TODOs: Tuples, Symboles, Littéraux XML. – missingfaktor
Je ne pense pas que le XML s'adapte parce que ce n'est pas vraiment du sucre dans le sens de sténographie d'autre chose. Je suis d'accord sur les Tuples et les Symboles. –
Si vous avez vu le code exécuté pour construire les instances DOM XML correspondant à un littéral XML, je pense que vous devez convenir que les littéraux sont une abréviation! –