Flusso di controllo

<!-- verified-against: seed-llvm; examples: docs-examples-test -->

Condizioni e cicli

fn classify(value: i64, values: [3]i64) -> i64 {
    let label = if value > 0 { 1 } else if value < 0 { -1 } else { 0 }

    let mut index: usize = 0
    let mut total = label
    while index < len(values) {
        total += values[index]
        index = index + 1
    }

    for item in values {
        total += item
    }

    total
}

if è un'espressione. while e for supporto break e continue. Un ciclo guidato da name: può essere preso di mira da cicli nidificati con break :name / continue :name; semplice break/continue continua a significare il ciclo più interno ed è consentito il riutilizzo sequenziale di un'etichetta. L'uscita esegue la pulizia specifica del bordo per ogni ambito intermedio e non attraversa mai a spawn confine. Etichettato break/continue non assumere alcun valore. for su intervalli, array, sezioni e text/buffer valori (str, string, bytes, shared_bytes) si riduce a un'assegnazione diretta esente index/length ciclo. Rendimento di testo e buffer u8 elementi (unità byte, indicizzazione corrispondente); gli elementi di solo spostamento richiedono un'indicizzazione esplicita e la gestione della proprietà. enumerate segue gli stessi tipi con a usize indice.

Match e ADT

enum Response {
    Ok(i64)
    Err(str)
}

fn status(value: Response) -> i64 {
    match value {
        Ok(code) => code
        Err(message) => -1
    }
}

I bracci di corrispondenza non necessitano di virgole a meno che il confine non sia ambiguo: un braccio il cui corpo termina con un'espressione seguita da un modello (/[ richiede la virgola (B044). La corrispondenza deve essere esaustiva a meno che il flusso rimanente non sia irraggiungibile. I modelli supportano valori letterali, tuple, strutture, varianti, associazioni, scarti e protezioni. I carichi utili di solo spostamento vengono trasferiti solo quando viene selezionato un braccio; un modello o una guardia falliti preservano il proprietario per le armi successive.

if let e while let

fn label(found: ?string) -> i64 {
    if let Some(text) = found { len(text) as i64 } else { 0 }
}

fn count_down(from: ?i64) -> i64 {
    let mut total: i64 = 0
    let mut current = from
    while let Some(value) = current {
        total += value
        if value > 0 { current = Some(value - 1) } else { current = None }
    }
    total
}

Entrambi sono forme superficiali finite match e desugar in una partita a due bracci il cui secondo braccio è il complemento, così vincolante, move/borrow comportamento, esaustività e pulizia sono esattamente le regole della partita. if let Some(...) nomina il suo complemento None; un'altra variante del modello mantiene una mano jolly, che H032 rifiuta quando lo scrutatore trasporta un carico utile di solo movimento (scrivi il file esplicito match braccia lì) e uno schema inconfutabile (while let name = value) è respinto come H029.

Opzioni, risultati e ?

fn find(enabled: bool) -> ?i64 {
    if enabled { Some(42) } else { None }
}

fn forward(enabled: bool) -> ?i64 {
    let value = find(enabled)?
    Some(value)
}

? restituisce il present/success payload o restituisce l'errore corrispondente. La propagazione dei risultati può modificare il tipo di successo ma preserva il tipo di errore. Non si verifica alcuna allocazione o clonazione implicita. ? non può attraversare a spawn confine.

Pulitura sui bordi del flusso

Fallthrough, return, break, e continue eseguire il piano di pulizia verificato per i proprietari viventi. Panic/trap/abort i bordi non si rilassano mai e non eseguono alcuna pulizia.