Il BDR è bello ma è un po' caotico. Prima di tutto i buggles scorrazzano in tutte le direzioni e dopo il codice che si dovrà scrivere per farli muovere risulterà piuttosto difficile da leggere. Quì c'è un nuovo mondo BDR dove i buggle danzeranno dolcemente in cerchio. Approfitteremo di questa tranquillita per pulire un po' il vostro codice grazie al nuovo costrutto che introdurremo.
switch
conditionals[/!][!scala]Pattern matching[/!]La parte difficile del codice precedente era sicuramente la cascata di condizioni. Da qualche parte nel vostro codice sicuramente avrete avuto qualcosa di simile ad:
if ([!java|c]getIndication() == 'R'[/!][!scala]readMessage() == "R"[/!]) {
right();
[!c]stepForward()[/!][!java|scala]forward()[/!];
} else if ([!java|c]getIndication() == 'L'[/!][!scala]readMessage() == "L"[/!]) {
left();
[!c]stepForward()[/!][!java|scala]forward()[/!];
} else if ([!java|c]getIndication() == 'I'[/!][!scala]readMessage() == "I"[/!]) {
back();
[!c]stepForward()[/!][!java|scala]forward()[/!];
/* other else if */
} else {
finished = [!c]1[/!][!java|scala]true[/!];
}
When you review this code, it may not be clear at the first glance that it
is simply a choice with 4 branches depending on the value of
[!java|c]getIndication()[/!][!scala]readMessage()[/!]. To improve this, we
will use a [!java|c]switch
construct, which Java syntax is the
following:[/!] [!scala] pattern matching, which is a very powerful construct
that greatly generalizes the if
. It is arguably one of the
major advantages of Scala when compared to languages such as Java or
python. It is not new either, as other languages such as OCaml or Haskell
offer this feature since long, but still. It's really cool![/!]
switch (espressione) { case primoValore: cosaFareSeLespressioneCombaciaColPrimoValore(); break; case secondoValore: cosaFareSeLespressioneCombaciaColSecondoValore(); break; case terzoValue: cosaFareSeLespressioneCombaciaColTerzoValore(); break; /* tutti i casi simili che vuoi */ default: cosaFareSeLespressioneNonCombaciaConNessunValore(); }
Osserva che ogni alternativa dello switch deve finire con un
break
. Se ve lo dimenticate il pc andra avanti ad eseguire
l'alternativa successiva a quella cui si è balzati. Ci sono anche alcuni
rari casi dove questo comportamento può rivelarsi utile.
È poi possibile riscrivere il precedente codice BDR in modo più pulito utilizzando il costrutto switch.
switch (getIndication()) { case 'R': right(); [!c]stepForward()[/!][!java]forward()[/!]; break; case 'L': left(); [!c]stepForward()[/!][!java]forward()[/!]; break; case 'I': back(); [!c]stepForward()[/!][!java]forward()[/!]; break; default: return; }[/!] [!scala]
espressione match { case valore possibile => istruzioni case altro valore => altre istruzioni case un altro valore => ancora altre istruzioni case _ => istruzioni predefinite }
All'inizio viene valutata l'espressione posta prima della parola chiave
match
e subito dopo quelli delle alternative fintantoché non si
trova il valore poste fra case
ed =>
uguale a
quello dell'espressione. Il simbolo _
agisce come jolly in modo
che l'alternativa _
sia sempre valida. Ecco un esempio
dove una variabile name
è comparata.
name match { case "Martin" => println("Ciao Martin, come stai?") case "Gerald" => println("Hey Gerald! How are you doing?") case _ => println("Benvenuto straniero.") }
È possibile avere più di una istruzione per alternativa ed unire più alternative separando i valori con il simbolo | .
name match { case "Martin" | "Gerald" => println("Ciao "+name+", come stai?"); openTheDoor() case _ => println("Ciao straniero. Per piacere non passare."); chiudiLaPorta() }
Puoi anche aggiungere protezioni alle tue alternative. Queste sono condizioni extra che devono essere rispettate perché l'alternativa venga applicata. È utile quando volete comparare intervalli di valori, come nell'esempio seguente.
anni match { case i if i<10 => println("Hey bambino!") case i if i<20 => println("Hey ragazzo!") case i if i<30 => println("Salve giovane uomo") case _ => println("Salve Signore") }
Nota che non c'è bisogno di controllare se il valore è più alto di 10 nella seconda riga perché le alternative sono considerate in ordine. Quindi, se la seconda alternativa viene valutata vuol dire che la prima non ha avuto corrispondenza.
Finalmente è possibile anche confrontare più variabili in un sol colpo!
(x,y) match { case (0,0) => println("questa è l'origine") case (_,0) => println("On the ordinate") case (0,_) => println("Sulle ascisse") case (_,_) => println("Alcuni punti casuali") }
Io vi dicevo che il pattern matching di scala è veramente potente! Io attualmente amo questa caratteristica!
[/!][!java|scala|c]Apply the improvement we just saw to rewrite your buggle code with the following dance steps. [/!] [!python]Let's teach a new dance step to the buggles. It is slightly more complex but actually better looking. Beside of that, that's the same old story.[/!] Note that we can now move up to 6 cells in one dance step.
Messaggi | Cosa fa |
[!java|c]'R'[/!][!scala|python]"R"[/!] | Gira a destra e muoviti un passo in avanti |
[!java|c]'L'[/!][!scala|python]"L"[/!] | Gira a sinistra e muoviti un passo in avanti |
[!java|c]'I'[/!][!scala|python]"I"[/!] | Girati indietro e muoviti un passo in avanti |
[!java|c]'A'[/!][!scala|python]"A"[/!] | Muoviti un passo avanti |
[!java|c]'B'[/!][!scala|python]"B"[/!] | Muoviti due passi in avanti |
[!java|c]'C'[/!][!scala|python]"C"[/!] | Muoviti tre passi in avanti |
[!java|c]'D'[/!][!scala|python]"D"[/!] | Muoviti quattro passi in avanti |
[!java|c]'E'[/!][!scala|python]"E"[/!] | Muoviti cinque passi in avanti |
[!java|c]'F'[/!][!scala|python]"F"[/!] | Muoviti sei passi in avanti |
[!java|c]'Z'[/!][!scala|python]"Z"[/!] | Muoviti un passo indietro |
[!java|c]'Y'[/!][!scala|python]"Y"[/!] | Muoviti due passi indietro |
[!java|c]'X'[/!][!scala|python]"X"[/!] | Muoviti tre passi indietro |
[!java|c]'W'[/!][!scala|python]"W"[/!] | Muoviti quattro passi indietro |
[!java|c]'V'[/!][!scala|python]"V"[/!] | Muoviti cinque passi indietro |
[!java|c]'U'[/!][!scala|python]"U"[/!] | Muoviti sei passi indietro |
(qualsiasi altra cosa) | Fine delle danze |
Quan il tuo programma funzionerà di nuovo, procedi con il prossimo esercizio.