Rust 链接结果(组合器)

JGF*_*FMK 3 combinators rust

我一直在关注 Rust 教程,其中声称一个函数的两个版本会生成相同的结果:

版本 1:

pub fn get_transactions(fname:&str) -> Result<Vec<Transaction>,String> {
    let s = match std::fs::read_to_string(fname){
        Ok(v)=>v,
        Err(e)=> return Err(e.to_string()),
    };
    let t:Vec<Transaction> = match serde_json::from_str(&s) {
        Ok(v)=>v,
        Err(e)=> return Err(e.to_string()),
    };
    Ok(t)
}
Run Code Online (Sandbox Code Playgroud)

版本 2:

fn get_transactions_b(fname:&str) -> Result<Vec<Transaction>,String> {
    std::fs::read_to_string(fname)
    .map_err(|e| e.to_string())
    .and_then(|ld| serde_json::from_str(&ld) )
    .map_err(|e| e.to_string())
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到版本 2 的以下消息:

类型不匹配

预期结构std::string::String,找到结构serde_json::error::Error

注意:预期枚举std::result::Result<_, std::string::String> 发现枚举std::result::Result<_, serde_json::error::Error>

帮助:尝试使用预期枚举的变体:_::_serde::export::Ok(serde_json::from_str(&ld))


我无法从中做出头部或尾部:

  • 将鼠标悬停|ld|在 VS Code 中的ld 闭包参数上,它表示它属于类型std::string::String

  • 将鼠标悬停在 ld 上,from_str(&ld)我会收到消息。

  • 现在我明白 aResult由 anOk和 an 组成Err,但我认为组合器链接会起作用。

  • 编译器建议的修复也不起作用。

    • (或有道理):这到底是_::_怎么回事?
    • 为什么Ok不在 from_str 里面?
  • 您需要做什么才能使版本 2 正常工作?

这是Rust 文档中组合器方法的结果


Cargo.toml

[dependencies]
serde = "1.0.115"
serde_derive = "1.0.115"
serde_json = "1.0.57"
Run Code Online (Sandbox Code Playgroud)
  • 货物 1.45.1
  • 生锈 1.45.2

Sun*_*eef 5

问题来自于and_then调用。

调用时不允许更改错误类型and_then。所以你的函数应该返回一个Result<Vec<Transaction>, String>. 但是,返回的错误类型serde_json::from_strserde_json::error::Error.

你可以像这样修复它:

std::fs::read_to_string(fname)
    .map_err(|e| e.to_string())
    .and_then(|ld| serde_json::from_str(&ld).map_err(|e| e.to_string()))
Run Code Online (Sandbox Code Playgroud)

请注意,对 的调用map_err现在位于传递给 的函数内and_then