【发布时间】:2019-09-18 14:37:36
【问题描述】:
我一直在玩有趣的SNAFU library。
来自 SNAFU 页面的稍作修改的独立示例如下:
use snafu::{ResultExt, Snafu};
use std::{fs, io, path::PathBuf};
#[derive(Debug, Snafu)]
enum Error {
#[snafu(display("Unable to read configuration from {}: {}", path.display(), source))]
ReadConfiguration { source: io::Error, path: PathBuf },
}
type Result<T, E = Error> = std::result::Result<T, E>;
fn process_data() -> Result<()> {
let path = "config.toml";
let read_result: std::result::Result<String, io::Error> = fs::read_to_string(path);
let _configuration = read_result.context(ReadConfiguration { path })?;
Ok(())
}
fn main() {
let foo = process_data();
match foo {
Err(e) => println!("Hello {}", e),
_ => println!("success")
}
}
我所做的更改是使Result 上的类型从fs::read_to_string(path) 在process_data() 中显式化。
鉴于此,我无法理解 read_result 如何使用 context 方法,因为 std::result::Result 文档没有对上下文进行任何引用(如果您去掉SNAFU 的东西并尝试访问上下文)。
这里使用的模式对我来说并不明显。我幼稚的理解是,由于孤儿规则,无法扩展外部类型,但这里发生的事情看起来很像这样的扩展。
我也对type Result... 行感到困惑。我知道类型别名,但不使用左侧分配了泛型的语法。显然,这是设计模式的重要组成部分。
我的要求是澄清这里使用的是什么模式以及它是如何工作的。它似乎了解了 Rust 的一些非常有趣的方面。值得进一步阅读!
【问题讨论】:
-
很高兴你喜欢它!
-
@Shepmaster 是的,它有一个非常优雅的 API!
标签: design-patterns rust idioms