Rust 链接结果(组合器)
Rust chaining Results (Combinators)
我一直在关注 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)
}
版本 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())
}
但是,我收到版本 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))
、
我无法从中得出头或尾:
在 VS Code 中将鼠标悬停在 ld 闭包参数 |ld|
上,它表示它的类型为 std::string::String
将鼠标悬停在 from_str(&ld)
中的 ld 上,我收到了消息。
现在我明白 Result
是由 Ok
和 Err
组成的,但我认为组合器链接会起作用。
编译器建议的修复也不起作用。
- (或有道理):
_::_
是什么意思?
- 为什么
Ok
不在 from_str 里面?
要使版本 2 正常工作,您需要做什么?
这是 Rust 文档中的 Result with the methods for combinators。
Cargo.toml
[dependencies]
serde = "1.0.115"
serde_derive = "1.0.115"
serde_json = "1.0.57"
- 货运 1.45.1
- rustc 1.45.2
问题来自 and_then
调用。
调用and_then
时不允许更改错误类型。
所以你的函数应该 return a Result<Vec<Transaction>, String>
。但是,由 serde_json::from_str
编辑的错误类型 return 是 serde_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()))
请注意,对 map_err
的调用现在位于传递给 and_then
的函数内。
我一直在关注 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)
}
版本 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())
}
但是,我收到版本 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))
、
我无法从中得出头或尾:
在 VS Code 中将鼠标悬停在 ld 闭包参数
|ld|
上,它表示它的类型为std::string::String
将鼠标悬停在
from_str(&ld)
中的 ld 上,我收到了消息。现在我明白
Result
是由Ok
和Err
组成的,但我认为组合器链接会起作用。编译器建议的修复也不起作用。
- (或有道理):
_::_
是什么意思? - 为什么
Ok
不在 from_str 里面?
- (或有道理):
要使版本 2 正常工作,您需要做什么?
这是 Rust 文档中的 Result with the methods for combinators。
Cargo.toml
[dependencies]
serde = "1.0.115"
serde_derive = "1.0.115"
serde_json = "1.0.57"
- 货运 1.45.1
- rustc 1.45.2
问题来自 and_then
调用。
调用and_then
时不允许更改错误类型。
所以你的函数应该 return a Result<Vec<Transaction>, String>
。但是,由 serde_json::from_str
编辑的错误类型 return 是 serde_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()))
请注意,对 map_err
的调用现在位于传递给 and_then
的函数内。