gpt4 book ai didi

rust - 如何编写一个宏来返回基于字符串的结构的实现方法?

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

灵感来自 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)
如何完成?

最佳答案

首先,我要感谢@Shepmaster,如果您的问题并不复杂,您的建议适用于大多数情况。但是需要处理 struct ,用户提供的一段代码,在这种情况下,我想出的唯一方法是使用宏规则来实现
一段时间后,我终于完成了。
在我们的例子中,简而言之,我们可以做

fn get_method(ind: &str) -> Option<&dyn Fn()> {
// the default type of $name::$func is fn(), function pointer
// it is recommended to convert into &dyn Fn() if you impl many methods
let methods = vec![ $(&$name::$func as &dyn Fn()),* ];
let inds = vec![$(stringify!($func)),*];
let mut i = 0;
for item in inds.iter() {
if item == &ind {
break;
} else {
i +=1;
}
}
if i <= inds.len() - 1 {
Some(methods[i])
} else {
None
}

}

关于rust - 如何编写一个宏来返回基于字符串的结构的实现方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64790850/

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