gpt4 book ai didi

rust - 发送要构造的宏的枚举变量

转载 作者:行者123 更新时间:2023-12-03 11:40:59 26 4
gpt4 key购买 nike

目前,我正在一个项目中使用多个返回不同错误的 crate 。我试图不对结果使用unwrap,而是使用问号语法将错误向上传递。
为了做到这一点,我创建了自己的错误枚举,该枚举针对我使用的不同包装箱中的不同类型的错误提供了变体,然后使用map_err将错误映射到我的错误枚举。我还决定将行和文件添加到重新映射错误的位置,以便可以看到遇到错误的位置。
我的错误枚举

#[derive(Debug, Clone)]
pub enum Error {
GameError(ggez::GameError, String),
RonError(ron::error::Error, String),
}
映射错误的示例
let rdr = filesystem::open(ctx, gen_conf_path)
.map_err(|e| {
Error::GameError(e, format!("at line {} in {}", line!(), file!()))
})?;
这样做的问题是,我需要发送给 map_err的闭包变得很长,并且每次都基本相同,除了我要映射到的enum变体。所以我想创建一个宏,为正确的枚举变量生成闭包。所以我可以写类似下面的东西。
let rdr = filesystem::open(ctx, gen_conf_path).map_err(map_to!(Error::GameError))?
并且 map_to!宏将生成我之前拥有的代码。
这可能吗?我可以将枚举变量发送到宏并让其构造它还是应该以完全不同的方式来执行此操作?

最佳答案

关于枚举变量的一个有趣的实现细节是,初始化程序实际上是函数。

We have another useful pattern that exploits an implementation detail of tuple structs and tuple-struct enum variants. These types use () as initializer syntax, which looks like a function call. The initializers are actually implemented as functions returning an instance that’s constructed from their arguments. We can use these initializer functions as function pointers that implement the closure traits, which means we can specify the initializer functions as arguments for methods that take closures

Advanced Functions and Closures - The Rust Programming Language


这意味着,如果您有一个 enum FooBar,它具有一个 Foo(i32, i32)变体,那么您可以使用 FooBar::Foo并将其作为 Fn(i32, i32) -> FooBar传递。
enum FooBar {
Foo(i32, i32),
Bar(String),
}

fn foo(f: fn(i32, i32) -> FooBar) -> FooBar {
f(1, 2)
}

fn bar<F>(f: F) -> FooBar
where
F: Fn(i32, i32) -> FooBar,
{
f(1, 2)
}

fn main() {
foo(FooBar::Foo);
bar(FooBar::Foo);
}

因此,如果您将枚举变量视为函数,那么您的宏将变得非常简单:
macro_rules! map_to {
($f:expr) => {
|e| {
$f(e, format!("at line {} in {}", line!(), file!()))
}
};
}
当然,这是假定 e始终是有效类型,相对于 map_to所使用的枚举变体而言。

关于rust - 发送要构造的宏的枚举变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66205516/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com