Fluxo de controle
<!-- verified-against: seed-llvm; examples: docs-examples-test -->
Condições e loops
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 é uma expressão. while e for suporte break e continue. Um loop liderado por name: pode ser direcionado a partir de loops aninhados com break :name / continue :name; simples break/continue continue significando o loop mais interno e a reutilização sequencial de um rótulo é permitida. A saída executa uma limpeza específica da borda para cada escopo intermediário e nunca cruza um spawn limite. Rotulado break/continue não tome nenhum valor. for sobre intervalos, matrizes, fatias e text/buffer valores (str, string, bytes, shared_bytes) reduz para um valor livre de atribuição direta index/length laço. Rendimento de texto e buffers u8 elementos (unidades de bytes, indexação correspondente); elementos somente movimentação requerem indexação explícita e tratamento de propriedade. enumerate segue os mesmos tipos com um usize índice.
Partida e ADTs
enum Response {
Ok(i64)
Err(str)
}
fn status(value: Response) -> i64 {
match value {
Ok(code) => code
Err(message) => -1
}
}
Os braços correspondentes não precisam de vírgulas, a menos que o limite seja ambíguo: um braço cujo corpo termina em uma expressão seguida por um padrão (/[ requer a vírgula (B044). A correspondência deve ser exaustiva, a menos que o fluxo restante seja inacessível. Os padrões suportam literais, tuplas, estruturas, variantes, ligações, descarte e guardas. As cargas úteis somente de movimentação são transferidas somente quando um braço é selecionado; um padrão ou guarda com falha preserva o proprietário para armas posteriores.
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
}
Ambas são formas superficiais match e açúcar para uma partida de dois braços cujo segundo braço é o complemento, tão vinculativo, move/borrow comportamento, exaustividade e limpeza são exatamente as regras de correspondência. if let Some(...) nomeia seu complemento None; outro padrão variante mantém um braço curinga, que H032 rejeita quando o examinado carrega uma carga útil somente de movimento (escreva o explícito match braços lá) e um padrão irrefutável (while let name = value) é rejeitado como H029.
Opções, resultados e ?
fn find(enabled: bool) -> ?i64 {
if enabled { Some(42) } else { None }
}
fn forward(enabled: bool) -> ?i64 {
let value = find(enabled)?
Some(value)
}
? produz o present/success carga útil ou retorna a falha correspondente. A propagação do resultado pode alterar o tipo de sucesso, mas preserva o tipo de erro. Nenhuma alocação implícita ou clone ocorre. ? não pode cruzar um spawn limite.
Limpeza nas bordas do fluxo
Queda, return, breake continue execute o plano de limpeza verificado para proprietários ativos. Panic/trap/abort as bordas nunca se desenrolam e não fazem limpeza.