Rust - from Mozilla

Altri cicli           

Anche Rust non si sottrae all'obbligo di fornire i consueti cicli disponibili in quasi tutti gli altri linguaggi.

Il primo di cui ci occupiamo in questo paragrafo è while. La sua sintassi, così come il suo uso, è semplicissima:

while condizione-booleana
{
istruzioni
}

  Esempio 7.1
1
2
3
4
5
6
7
8
9
10
 fn main()
{
  let x = 5;
  let mut y = 0;
  while y < x
  {
    println!("{}", y);
    y = y + 1;
  }
}

La condizione non deve necessariamente essere messa tra parentesi, come in altri linguaggi. E' evidente che la condizione di uscita deve essere ben ponderata, questo nell'esempio 7.1, è realizzato tramite l'istruzione alla riga 8, che incrementando y lo avvicina al valore soglia che è x = 5.

Se si vuole un ciclo infinito si può scrivere

while true
{
...
}

In realtà Rust prevede un'istruzione specifica per questo ultimo problema e tale istruzione è proprio loop. che ha una sintassi davvero minimale.:

loop
{
istruzioni
}

Vediamo l'esempio:

  Esempio 7.2
1
2
3
4
5
6
7
8
9
fn main()
{
  let mut x = 0;
  loop
  {
    println!("{}",x);
    x = x + 1;
  }
}

Quando eseguirete il programma, verranno stampati un'infinità di numeri fino a raggiungere il limite massimo possibile oppure, meglio, fino a che non lo chiuderete con CTRL+C.

Il ciclo for invece è un po' più complesso, anche rispetto ad altri linguaggi ma, per i nostri scopi, la cosa è del tutto trasparente. La sua sintassi generale è:

for variabile in espressione
{
istruzioni
}

solo in apparenza banale.

Il primo esempio è forse il caso più semplice e, probabilmente, quello più comune:

  Esempio 7.3
1
2
3
4
5
6
7
fn main()
{
  for x in 0..5
  {
    println!("{}", x);
  }
}

L'output è il seguente:

0
1
2
3
4

e ci dà un'indicazione ovvero che il numero 5 è escluso. E' quindi interessante notare che il range 0..n comprende i valori da 0 ad n-1. Da notare che non è possibile nelle versioni stabili definire un step diverso da 1. Per emulare la cosa bisogna ricorrere al while, definendo all'interno del corpo del while stesso, il passo che desideriamo (alla riga 8 dell'esempio 7.1 abbiamo definito un normnale passo 1). Usando una nightly potete scrivere invece:

for x in (0..10).step_by(2)

che, come detto, nella versione stabile che sto usando al momento, la 1.70, non è ammessa

Va detto che non potete nemmeno invertire il range: 5..0 corrisponde ad un range vuoto e quindi non restituisce alcuna iterazione.

Per tenere traccia delle iterazioni abbiamo un metodo molto rapido in Rust:

  Esempio 7.4
1
2
3
4
5
6
7
fn main()
{
  for (i,j) in (5..10).enumerate()
  {
    println!("i = {} and j = {}", i, j);
  }
}

Anche Rust prevede i classici meccanismi per interrompere un loop o fargli saltare un ciclo. Le keyword interessate sono rispettivamente break e continue.
La prima istruzione, come detto, interrompe il ciclo in cui si trova e restituisce il controllo al livello superiore. Il secondo salta un'iterazione ma il programma comunque resta all'interno del loop. Vediamo i due esempi col rispettivo output:

  Esempio 7.5
1
2
3
4
5
6
7
8
fn main()
{
  for x in 0..10
  {
    if x == 5 { break; }
    println!("{}", x);
  }
}

 

0
1
2
3
4

 

  Esempio 7.5
1
2
3
4
5
6
7
8
fn main()
{
  for x in 0..10
  {
    if x == 5 { continue; }
    println!("{}", x);
  }
}

 

0
1
2
3
4
6
7
8
9

Come si vede, nel primo caso viene bloccata l'esecuzione del ciclo appena si raggiunge il valore 5; nel secondo l'esecuzione prosegue ma l'istruzione alla riga 6 non viene eseguita per il valore 5.