Controle de Fluxo Let
Rust possui algumas construçÔes de fluxo de controle que diferem de outras linguagens. Elas sĂŁo usadas para correspondĂȘncia de padrĂ”es:
- ExpressÔes
if let
- ExpressÔes
let else
- ExpressÔes
while let
ExpressÔes if let
A expressĂŁo if let
lhe permite executar um cĂłdigo diferente caso um valor corresponde a um padrĂŁo:
use std::time::Duration; fn sleep_for(secs: f32) { if let Ok(dur) = Duration::try_from_secs_f32(secs) { std::thread::sleep(dur); println!("dormiu por {:?}", dur); } } fn main() { sleep_for(-10.0); sleep_for(0.8); }
ExpressÔes let else
Para o caso comum de corresponder a um padrão e retornar da função, use let else
. O caso "else" deve divergir (return
, break
ou pĂąnico - qualquer coisa, exceto cair no final do bloco).
fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> { let s = if let Some(s) = maybe_string { s } else { return Err(String::from("obteve None")); }; let first_byte_char = if let Some(first_byte_char) = s.chars().next() { first_byte_char } else { return Err(String::from("obteve uma string vazia")); }; if let Some(digit) = first_byte_char.to_digit(16) { Ok(digit) } else { Err(String::from("nĂŁo Ă© um dĂgito hexadecimal")) } } fn main() { println!("result: {:?}", hex_or_die_trying(Some(String::from("foo")))); }
Similar a if let
, hĂĄ uma variante while let
que testa repetidamente se um valor corresponde a um padrĂŁo:
fn main() { let mut name = String::from("Comprehensive Rust đŠ"); while let Some(c) = name.pop() { println!("character: {c}"); } // (There are more efficient ways to reverse a string!) }
Aqui String::pop
retorna Some(c)
até que a string esteja vazia e depois ela retornarå None
. O while let
nos permite iterar por todos os itens.
if-let
- Ao contrĂĄrio de
match
,if let
não precisa cobrir todas as ramificaçÔes. Isso pode tornå-lo mais conciso do quematch
. - Um uso comum Ă© lidar com valores
Some
ao trabalhar-se comOption
. - Ao contrĂĄrio de
match
,if let
nĂŁo suporta clĂĄusulas de guarda para correspondĂȘncia de padrĂ”es.
let-else
if-let
s podem se acumular, como mostrado. A construção let-else
permite o "achatamento" desse código aninhado. Reescreva a versão "estranha" para os alunos, para que eles possam ver a transformação.
A versĂŁo reescrita Ă©:
#![allow(unused)] fn main() { fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> { let Some(s) = maybe_string else { return Err(String::from("obteve None")); }; let Some(first_byte_char) = s.chars().next() else { return Err(String::from("obteve uma string vazia")); }; let Some(digit) = first_byte_char.to_digit(16) else { return Err(String::from("nĂŁo Ă© um dĂgito hexadecimal")); }; return Ok(digit); } }
while-let
- Ressalte que o loop
while let
continuarĂĄ executando enquanto o valor corresponder ao padrĂŁo. - VocĂȘ pode reescrever o loop
while let
como um loop infinito com uma instruçãoif
que Ă© interrompido quando nĂŁo houver mais nenhum valor para unwrap (desempacotar) paraname.pop()
. Owhile let
fornece um atalho para o cenĂĄrio acima.