Fácil Rust
Propagando erro de parse
Enunciado
Escreva uma função soma_strings que recebe duas strings, converte cada uma para i32 e retorna a soma. Use o operador ? para propagar erros de conversão. O retorno deve ser Result<i32, std::num::ParseIntError>.
Requisitos
- A função deve ter assinatura
fn soma_strings(a: &str, b: &str) -> Result<i32, ParseIntError>. - Deve usar
?para converter as strings. - Em caso de sucesso, retorna
Ok(soma).
Código inicial
use std::num::ParseIntError;
fn soma_strings(a: &str, b: &str) -> Result<i32, ParseIntError> {
// TODO: use ? para converter a e b, depois retorne Ok(soma)
}
fn main() {
println!("{:?}", soma_strings("10", "20"));
println!("{:?}", soma_strings("10", "x"));
}
Saída esperada
Ok(30)
Err(ParseIntError { kind: InvalidDigit })
Ver dica
Use let a: i32 = a.parse()?; e depois some. O ? já retorna o erro se a conversão falhar.
Mostrar solução
use std::num::ParseIntError;
fn soma_strings(a: &str, b: &str) -> Result<i32, ParseIntError> {
let a: i32 = a.parse()?; // se falhar, retorna Err(ParseIntError)
let b: i32 = b.parse()?; // idem
Ok(a + b) // sucesso
}
fn main() {
println!("{:?}", soma_strings("10", "20"));
println!("{:?}", soma_strings("10", "x"));
}
Passo a passo
- A função recebe duas
&stre declara retornoResult<i32, ParseIntError>. a.parse()?tenta converteraparai32. Se der certo, o valor é extraído; se der erro, oErré retornado imediatamente da função.- O mesmo ocorre com
b. - Se ambos forem convertidos, a soma é calculada e envolvida em
Ok. - No
main, imprimimos os resultados com{:?}para ver as variantes.
Por que funciona
O operador ? é açúcar sintático para um match: se o Result for Ok(v), ele avalia para v; se for Err(e), ele faz return Err(e) (com conversão via From se necessário). Como o tipo de erro da função é ParseIntError, não é necessária conversão.
Erros comuns
- Esquecer de anotar o tipo:
let a = a.parse()?;não compila porque o compilador não sabe para qual tipo converter. Solução:let a: i32 = a.parse()?;. - Usar
?emmainsem retornoResult:fn main() { let x = "1".parse::<i32>()?; }gera erro porquemainretorna(). Corrija fazendofn main() -> Result<(), ParseIntError>ou tratando o erro.
Outra forma de resolver
Sem ?, usando match:
fn soma_strings(a: &str, b: &str) -> Result<i32, ParseIntError> {
let a = match a.parse::<i32>() {
Ok(v) => v,
Err(e) => return Err(e),
};
// ...
}
Mais verboso; o ? é preferível.
Saída esperada
Ok(30)
Err(ParseIntError { kind: InvalidDigit })