【发布时间】:2020-11-11 17:01:06
【问题描述】:
受How to get struct field names in Rust? 的启发,我想获得一个基于str 的结构实现方法,类似于:
macro_rules! comp {
(struct $name:ident {
$($field_name:ident : $field_type:ty,)*
}
impl $name2:ident {
$(pub fn $func_name:ident($($args:tt)*) $bk:block)*
}
) => {
//basic component
struct $name {
$($field_name: $field_type),*
}
impl $name {
$(pub fn $func_name($($args)*) $bk)*
// the generated function
pub fn get_method(index: &str) -> &'static dyn Fn() {
$(if stringify!($func_name) == index {
return $func_name; // (***)
})*
//
// Some code here to return the right function
//
}
}
};
}
fn main() {
comp! {
struct S {
field: String,
}
impl S {
pub fn method1() {
println!("method1 called");
}
pub fn method2() {
println!("method2 called");
}
}
}
// the functionality should achieved
// S::get_method("method1") == S::method1
// S::get_method("method2") == S::method2
}
本来想用return $func_name获取函数指针,但是好像不可能;标有(***) 的代码行出现错误:
error[E0423]: expected function, found macro `stringify`
--> src/main.rs:19:22
|
19 | $(if stringify($func_name) == index {
| ^^^^^^^^^ not a function
...
31 | / comp! {
32 | | struct S {
33 | | field: String,
34 | | }
... |
42 | | }
43 | | }
| |_____- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: use `!` to invoke the macro
|
19 | $(if stringify!($func_name) == index {
| ^
error[E0425]: cannot find value `method1` in this scope
--> src/main.rs:36:20
|
36 | pub fn method1() {
| ^^^^^^^ not found in this scope
error[E0425]: cannot find value `method2` in this scope
--> src/main.rs:39:20
|
39 | pub fn method2() {
| ^^^^^^^ not found in this scope
error[E0308]: mismatched types
--> src/main.rs:19:19
|
19 | $(if stringify($func_name) == index {
| ___________________^
20 | | return $func_name; // (***)
21 | | })*
| |_________________^ expected reference, found `()`
...
31 | / comp! {
32 | | struct S {
33 | | field: String,
34 | | }
... |
42 | | }
43 | | }
| |_____- in this macro invocation
|
= note: expected reference `&'static (dyn std::ops::Fn() + 'static)`
found unit type `()`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
如何完成?
【问题讨论】:
-
看来Is there a way to perform an index access to an instance of a struct? 的答案可能会回答您的问题。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。
-
虽然重复返回字段,但返回函数指针应该是等效的。与往常一样,在尝试创建宏之前先手动编写代码。
标签: rust macros rust-macros