Estou lendo a documentação paraFile
:
//..
let mut file = File::create("foo.txt")?;
//..
O que está ?
nesta linha? Não me lembro de ter visto isso no Rust Book antes.
Estou lendo a documentação paraFile
:
//..
let mut file = File::create("foo.txt")?;
//..
O que está ?
nesta linha? Não me lembro de ter visto isso no Rust Book antes.
Respostas:
Como você deve ter notado, Rust não tem exceções. Há pânico, mas sua funcionalidade é limitada (eles não podem transportar informações estruturadas) e seu uso para tratamento de erros é desencorajado (eles são feitos para erros irrecuperáveis).
Em Rust, usa o tratamento de erros Result
. Um exemplo típico seria:
fn halves_if_even(i: i32) -> Result<i32, Error> {
if i % 2 == 0 {
Ok(i / 2)
} else {
Err(/* something */)
}
}
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = match halves_if_even(i) {
Ok(i) => i,
Err(e) => return Err(e),
};
// use `i`
}
Isso é ótimo porque:
É menos do que ideal, no entanto, por ser muito prolixo. É aqui que o operador ponto de interrogação ?
entra.
O texto acima pode ser reescrito como:
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = halves_if_even(i)?;
// use `i`
}
que é muito mais conciso.
O que ?
significa aqui é equivalente à match
afirmação acima. Resumindo: ele descompacta o Result
if OK e retorna o erro se não.
É um pouco mágico, mas o tratamento de erros precisa de um pouco de mágica para reduzir o clichê e, ao contrário das exceções, é imediatamente visível quais chamadas de função podem ou não dar erro: aquelas que são adornadas com ?
.
Um exemplo da mágica é que isso também funciona para Option
:
// Assume
// fn halves_if_even(i: i32) -> Option<i32>
fn do_the_thing(i: i32) -> Option<i32> {
let i = halves_if_even(i)?;
// use `i`
}
Isso é alimentado pelo Try
traço (instável) .
Veja também:
Result
ou Option
.
É para propagação de erro para o tipo de erro recuperável Resultado <T, E>. Ele desembrulha o resultado e lhe dá o valor interno.
Em vez de lidar com o caso de erro, você o propaga para o código do chamador e trata apenas do caso OK. A vantagem é que ele elimina muitos clichês e torna a implementação da função mais simples.
.unwrap()
que entra em pânico em caso de erro.