如何在声明性宏中提前 return 并推断 return 类型?
How do I early return in declarative macros and infer the return type?
我有一个宏,它只生成一个结构的实例,如下所示:
macro_rules! foo {
() => {{
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
return Err(err);
}
};
Ok(Foo(baz_val, bar_val))
}};
}
如您所见,我根据 bar()
函数的结果在宏中做了一个早期的 return。然而,这是一个错误,说:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:23:24
|
23 | return Err(err);
| ^^^^^^^^ expected `()`, found enum `Result`
...
32 | let foo_val = foo!();
| ------ in this macro invocation
|
= note: expected unit type `()`
found enum `Result<_, String>`
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0308`.
Here's also the permalink to the playground 具有完整的最小可重现样本。
我认为这里的问题是类型推断。我想 return 示例中 FooResult
的实例,但宏无法推断它。
那么,如何在声明性宏中提前 return 和 infer/define 输入 return?
环境
- rustc 1.55.0
return
用于函数而不是宏。对于预期的行为,您可以将宏包装到闭包中并立即调用它:
macro_rules! foo {
() => {{
(|| {
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
return Err(err);
}
};
Ok(Foo(baz_val, bar_val))
})()
}};
}
@Netwave 的答案的另一种选择是使用夜间专用功能 label-break-value
,如下所示:
#![feature(label_break_value)]
macro_rules! foo {
() => {'foo: {
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
break 'foo Err(err);
}
};
Ok(Foo(baz_val, bar_val))
}};
}
我相信这个功能被明确设计为能够从任意块“return”,这几乎是你的情况。
我有一个宏,它只生成一个结构的实例,如下所示:
macro_rules! foo {
() => {{
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
return Err(err);
}
};
Ok(Foo(baz_val, bar_val))
}};
}
如您所见,我根据 bar()
函数的结果在宏中做了一个早期的 return。然而,这是一个错误,说:
Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
--> src/main.rs:23:24
|
23 | return Err(err);
| ^^^^^^^^ expected `()`, found enum `Result`
...
32 | let foo_val = foo!();
| ------ in this macro invocation
|
= note: expected unit type `()`
found enum `Result<_, String>`
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0308`.
Here's also the permalink to the playground 具有完整的最小可重现样本。
我认为这里的问题是类型推断。我想 return 示例中 FooResult
的实例,但宏无法推断它。
那么,如何在声明性宏中提前 return 和 infer/define 输入 return?
环境
- rustc 1.55.0
return
用于函数而不是宏。对于预期的行为,您可以将宏包装到闭包中并立即调用它:
macro_rules! foo {
() => {{
(|| {
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
return Err(err);
}
};
Ok(Foo(baz_val, bar_val))
})()
}};
}
@Netwave 的答案的另一种选择是使用夜间专用功能 label-break-value
,如下所示:
#![feature(label_break_value)]
macro_rules! foo {
() => {'foo: {
let baz_val = baz();
let bar_val = match bar() {
Ok(val) => val,
Err(err) => {
break 'foo Err(err);
}
};
Ok(Foo(baz_val, bar_val))
}};
}
我相信这个功能被明确设计为能够从任意块“return”,这几乎是你的情况。