Rust - from Mozilla

Istruzione "if"               
 
La sintassi di questa istruzione non differisce rispetto a molti altri linguaggi. Il primo caso è quello semplice che vede questa istruzione di selezione legata ad un singolo branch, ad una singola ramificazione; vediamo la sintasi e  poi subito l'esempio:

if condizione booleana
{
  istruzioni
}

laddove con "condzione booleana" si intende ovviamente una espressione il cui risultato può essere vero o falso.

  Esempio 2.1
1
2
3
4
5
6
7
8
fn main()
{
  let x = 5;
  if x == 5
  {
    println!("cinque!")
  }
}

La forma successiva ha invece il formato:

if condizione booleana
{
  istruzioni
}
else
{
  istruzioni
}

L'esempio successivo è un po' più complesso e potrebbe dover essere modificato nelle versioni successive del linguaggio, comunque da esso impareremo qualcosa di più sul linguaggio:

  Esempio 2.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn main()
{
  print!("Inserisci un numero: ");
  let input = std::old_io::stdin().read_line().ok().expect("Failed to read line");
  let result: i32 = (input.trim()).parse().unwrap();
  if result % 2 == 0
  {
    println!("Hai inserito un numero pari");
  }
  else
  {
    println!("Hai inserito un numero dispari");
  }
}

Dalla riga 6 alla 13, chiusura dell'else, vediamo realizzato quanto appena spiegato. Le righe precedenti sono un po' più complicate e danno l'idea del livello di difficoltà che almeno inizialmente può proporre questo linguaggio. La 4 propone la "smplice" lettura di una stringa dall standard input. La 5 il cast da stringa da intero 32 bit, ovvero la trasformazione della stringa digitata in input in valore numerico intero. Le istruzioni non sono così semplici come in altri linguaggi ma per ora non approfodnisco il discorso prevedendo qualche evoluzione in merito.
La terza forma del nostro comando di selezione è invece:

if condizione booleana
{
  istruzioni
}
else if condizione booleana
{
  istruzioni
}
else if condizione booleana
{
  istruzioni
}
.....
else
{
  istruzioni
}

ad esempio:

  Esempio 2.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
fn main()
{
  print!("Inserisci un numero: ");
  let input = std::old_io::stdin().read_line().ok().expect("Failed to read line");
  let result: i32 = (input.trim()).parse().unwrap();
  if result == 0
  {
    println!("Hai inserito lo 0");
  }
  else if result == 1
  {
    println!("Hai inserito il numero 1");
  }
  else
  {
    println!("numero > 1");
  }
}

che mette in pratica quanto visto. Il numero di ramificazioni può essere grane a piacere ma è meglio limitarsi in questo aspetto a non più di 4 o 5, dopo di che bisognerà ripensare al proprio programma e ricorrere eventualmente al pattern matching, che vedremo altrove.
Come in altri linguaggi di programmazione, le condizioni devono essere mutuamente esclusive (è naturale, si capisce) e se un branch viene eseguito tutti gli altri, come logica e praticamente, vengono saltati.

Il nostro if ci permette anche un suo uso "funzionale":

let y = if x == 5
{
 10
}
else
{
 15
};

ovvero viene attribuito un valore sulla base del ramo che si verifica. Molto elegante. Molto "expression based". Questo spezzone di codice, che gira perfettamente, dimostra che in Rust un'espressione come "if" restituisce comunque un valore.