rust - 如何制作递归宏来分解此代码?
问题描述
我试图制作一个分解一些代码的宏。
trait Animal {
fn crie(&self) -> String;
fn crie_plusieurs_fois(&self, n: isize) -> String {
let mut res = "".to_string();
if n > 0 {res = self.crie() + " " + &*res + &*self.crie_plusieurs_fois(n - 1) }
res
}
}
struct Chien {}
struct Chat {}
impl Animal for Chien {
fn crie(&self) -> String {
"wouaf".to_string()
}
}
impl Animal for Chat {
fn crie(&self) -> String {
"miaou".to_string()
}
}
我有这个,我想创建这个:
enum Animals{
CHIEN(Chien),
CHAT(Chat)
}
impl Animal for Animals{
fn crie(&self) -> String {
match self {
Animals::CHIEN(c) => c.crie(),
Animals::CHAT(c) => c.crie(),
}
}
}
使用这些递归宏:
macro_rules! impl_trait_for_enum{
(
$nom_trait: ident;
$nom_enum: ident => $($nom_fonction:ident($($nom_var:ident : $type_var:ty),*) $(-> $type_retour:ty)?),+ ;
$($identifiant : ident => $structure : ident),+
) => {
enum $nom_enum{
$($identifiant($structure)),+
}
impl $nom_trait for $nom_enum {
impl_trait_function!($nom_enum; $($identifiant),+; $($nom_fonction ($($nom_var : $type_var),*) $(-> $type_retour)?),*);
}
}
}
macro_rules! impl_trait_function{
(
$nom_enum: ident;
$($identifiant: ident ),*;
$nom_fonction: ident($($nom_var:ident : $type_var:ty),*) $(-> $type_retour:ty)?,
$($autre_nom_fonction: ident($($autre_nom_var:ident : $ autre_type_var:ty),*) $(-> $autre_type_retour:ty)?),*
)=> {
fn $nom_fonction(&self$(,$nom_var: $type_var),* ) $(-> $type_retour)? {
match self {
impl_multiple_pattern!($nom_enum;$nom_fonction($($nom_var),*); $($identifiant),*);
}
}
impl_trait_function!($nom_enum; $($identifiant),+;
$($autre_nom_fonction ($($autre_nom_var : $ autre_type_var),*) $(-> $autre_type_retour)?),*);
};
($nom_enum: ident; $($identifiant: ident),+;) => {}
}
macro_rules! impl_multiple_pattern {
(
$nom_enum: ident;
$nom_fonction: ident($($nom_var: ident),*);
$identifiant: ident,
$($autre_identifiant: ident),*
)=>{
$nom_enum::$identifiant(s) => s.$nom_fonction($(nom_var: ident)*),
impl_multiple_pattern($nom_enum; $nom_fonction($($nom_var)*); $rest);
};
(
$nom_enum: ident;
$nom_fonction: ident($($nom_var: ident)*);
) => {}
}
这个电话
impl_trait_for_enum!( Animals; Animal => crie() -> String, crie_plusieur_fois(n: isize) -> String;
Dog => Chien,
Cat => Chat
);
我有这个错误:
error: expected one of `=>`, `if`, or `|`, found `;`
--> src/main.rs:101:98
|
101 | impl_multiple_pattern!($nom_enum;$nom_fonction($($nom_var),*); $($identifiant),*);
| ^ expected one of `=>`, `if`, or `|`
...
134 | / impl_trait_for_enum!(
135 | | Animal; Animals => crie() -> String, crie_plusieurs_fois(n: isize) -> String;
136 | | Dog => Chien,
137 | | Cat => Chat
138 | | );
| |__________- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: unexpected end of macro invocation
--> src/main.rs:105:115
|
89 | macro_rules! impl_trait_function{
| -------------------------------- when calling this macro
...
105 | $($autre_nom_fonction ($($autre_nom_var : $ autre_type_var),*) $(-> $autre_type_retour)?),*);
| ^ missing tokens in macro arguments
目标是拥有一个对象集合,其中包含实现相同特征的不同对象,而使用类似“Vec< dyn Trait>”的东西,因为有时我必须根据对象制作不同的东西。
我使用枚举和匹配模式的解决方案运行良好,但我正在编写很多类似的代码。这就是我试图通过这些宏来避免的。
我不允许像这样在匹配模式中调用宏:
match self {
impl_multiple_pattern!($nom_enum;$nom_fonction($($nom_var),*); $($identifiant),*);
}
我的想法不可能用宏来实现吗?
解决方案
推荐阅读
- javascript - 如何使 JS for 循环异步
- php - 替换bbcode标签php中的反斜杠和引号
- r - 按行条件 data.table 应用两个函数
- java - 从 Libs 文件夹更改 Gradle 编译 .jar 路径
- python - 如何使用 jQuery Ajax 调用 Django 视图从数据库中检索数据
- c - 为什么具有位域的结构的大小大于应有的大小?
- heroku - Heroku:编辑已安装的 python 库的文件
- webpack - Webpack:使用外部注入需求
- symfony - Symfony 3 - 教义 2:聚合子句不起作用
- python - 正则表达式 - 提取年份