Eu tenho uma função que retorna um Result
tipo. Dentro dessa função, outra função está sendo chamada, que retorna Result
o tipo. E, se o valor retornado for uma Err
variante, chame uma função/fechamento antes de borbulhar esse erro, senão, se for uma Ok
variante, chame uma função/fechamento e então simplesmente retorne o valor contido. Isso é o que eu escrevi até agora
fn foo1() -> Result<i32, String> {
Err("error".to_string())
}
fn foo2() -> Result<String, bool> {
let res = foo1().map_err(|err| {
println!("foo1 failed {}", err);
false
})?;
// I know I can call some closure in here, but I want something like map_err which will call different closures depending on the Result variant
Ok(res.to_string())
}
fn main() {
foo2();
}
Eu diria que você provavelmente chegou a um ponto em que suas necessidades são suficientemente especializadas para que você deva simplesmente implementar
match
o que realmente precisa.Combinadores e funções de ordem superior existem para sinalizar caminhos e fornecer informações semânticas ao leitor, mas se eles não se aplicam diretamente ou não deixam as coisas mais claras, é perfeitamente aceitável e esperado que não sejam usados .
Então podemos desaçucarar seu snippet para isto:
e não acho que estamos em pior situação por isso. Na verdade, é bem o oposto: o uso de um raw
match
na verdade sinaliza ao leitor (incluindo o seu futuro) que estamos realizando um conjunto não óbvio de transformações.Acho que posso usar uma combinação de
map
métodosmap_err
como abaixo