methods - 无论如何, “context”和 “with_context”有什么区别?

标签 methods error-handling rust closures lazy-evaluation

这是有关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/

相关文章:

c# - 使用类型对象作为返回类型 - 不好的做法?

asp.net - 登录不正确时显示消息

assembly - 计算平均值

rust - 试图耗尽一个字符串并映射到它的字符上,但由于类型推断而失败

rust - 在删除 Rust Future 时 panic 运行异步代码

rust - 如何将已经构建的 rust 库添加到 cargo build 中?

PHP 两个同名方法

java - 在我的几乎所有脚本中使用相同的自定义方法

methods - 使用 TDD 方法并避免使用 Java 静态方法

php - Codeigniter 3 show_404函数问题-MY_Exception无法加载