这是有关Context的文档:
/// Wrap the error value with additional context.
fn context<C>(self, context: C) -> Result<T, Error>
where
C: Display + Send + Sync + 'static;
/// Wrap the error value with additional context that is evaluated lazily
/// only once an error does occur.
fn with_context<C, F>(self, f: F) -> Result<T, Error>
where
C: Display + Send + Sync + 'static,
F: FnOnce() -> C;
实际上,不同之处在于with_context
需要关闭,如反正README所示:use anyhow::{Context, Result};
fn main() -> Result<()> {
// ...
it.detach().context("Failed to detach the important thing")?;
let content = std::fs::read(path)
.with_context(|| format!("Failed to read instrs from {}", path))?;
// ...
}
但是看起来我可以用with_context
替换context
方法,通过删除||
摆脱闭包,并且程序的行为不会改变。两种方法的内在区别是什么?
最佳答案
提供给with_context
的闭包是惰性计算的,而您选择使用with_context
而不是context
的原因与您选择惰性计算任何事物的原因相同:它很少发生,并且计算成本很高。一旦满足这些条件,with_context
就比context
更可取。注释的伪示例:
fn calculate_expensive_context() -> Result<()> {
// really expensive
std::thread::sleep(std::time::Duration::from_secs(1));
todo!()
}
// eagerly evaluated expensive context
// this function ALWAYS takes 1+ seconds to execute
// consistently terrible performance
fn failable_operation_eager_context(some_struct: Struct) -> Result<()> {
some_struct
.some_failable_action()
.context(calculate_expensive_context())
}
// lazily evaluated expensive context
// function returns instantly, only takes 1+ seconds on failure
// great performance for average case, only terrible performance on error cases
fn failable_operation_lazy_context(some_struct: Struct) -> Result<()> {
some_struct
.some_failable_action()
.with_context(|| calculate_expensive_context())
}
关于methods - 无论如何, “context”和 “with_context”有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65459952/