In primo luogo, apply
e unapply
non sono necessariamente opposti l'uno dall'altro. Infatti, se ne definisci uno su una classe/oggetto, non devi definire l'altro.
applicano
apply
è probabilmente il più facile da spiegare. Essenzialmente, quando tratti il tuo oggetto come una funzione, applica è il metodo che viene chiamato, quindi Scala gira:
obj(a, b, c)
a obj.apply(a, b, c)
.
unapply
unapply
è un po 'più complicato. È utilizzato nel meccanismo di corrispondenza dei modelli di Scala e il suo uso più comune che ho visto è in Extractor Objects.
Per esempio, ecco un oggetto giocattolo estrattore:
object Foo {
def unapply(x : Int) : Option[String] =
if(x == 0) Some("Hello, World") else None
}
Così ora, se si utilizza questo è in un match modello in questo modo:
myInt match {
case Foo(str) => println(str)
}
Supponiamo myInt = 0
. Allora cosa succede? In questo caso viene chiamato il numero Foo.unapply(0)
e, come puoi vedere, restituirà Some("Hello, World")
. Il contenuto di Option
verrà assegnato a str
quindi, alla fine, la corrispondenza del modello sopra verrà stampata "Ciao, mondo".
Ma cosa succede se myInt = 1
? Quindi Foo.unapply(1)
restituisce None
in modo che l'espressione corrispondente per tale modello non venga chiamata.
Nel caso di incarichi, come val Foo(str) = x
questo è zucchero sintattico per:
val str : String = Foo.unapply(x) match {
case Some(s) => s
case None => throw new scala.MatchError(x)
}
un po 'strano che hai chiamato l'int 'str' ma a parte questo, molto bello spiegazione;) – Nicofisi
il punto è che 'str' è in realtà un' String' non un 'Int', perché questo è un tipo molto particolare di oggetto estrattore :) – amnn