【发布时间】:2020-03-21 06:03:00
【问题描述】:
我想使用macro_rules! 实现一个结构,因为泛型需要大量样板文件和特征搜索。
有问题的结构内部有一个哈希表,但键和值类型由用户提供。代码如下:
macro_rules! new_ytz {
($T: ty) => {
// define the struct
pub struct Ytz {
table: hashbrown::hash_map::HashMap<$T, $T>,
}
impl Ytz {
pub fn new() -> Self {
Ytz {
table: hashbrown::hash_map::HashMap::<$T, $T>::new(),
}
}
pub fn add(&mut self, item: &$T) {
if self.table.contains_key(item) {
*self.table.get_mut(item).unwrap() += *item;
} else {
self.table.insert(*item, *item);
}
}
pub fn largest(&self) -> $T {
let mut result = 0;
for v in self.table.values() {
if result < *v {
result = *v;
}
}
result
}
}
// construct an instance of the struct and return it
Ytz::new()
};
}
// driver
fn main() {
let mut y = new_ytz!(u64); // should construct the object and return Ytz::new()
y.add(&71);
y.add(&25);
y.add(&25);
y.add(&25);
y.add(&34);
println!("{}", y.largest());
}
这不会编译,因为它试图将结构粘贴到主函数中:
error: expected expression, found keyword `pub`
--> src/main.rs:4:9
|
4 | pub struct Ytz {
| ^^^ expected expression
...
40 | let mut y = new_ytz!(u64); // should construct the object and return Ytz::new()
| ------------- in this macro invocation
我该如何解决?如何将结构与 impl 块一起公开粘贴到主函数之外?
【问题讨论】:
-
你不能这样做。
-
为什么要让生活变得复杂?
-
这是因为狩猎特性很难。例如,为了概括这一点,我必须手动查找许多不同类型的特征和大量编译/失败/查找宏/添加特征等。这个 (play.rust-lang.org/…) 看起来很丑,但现在可以完成工作。
-
特征搜索是什么意思?我可以不用看 Rust 的文档就告诉你
T需要实现Hash、Eq和Ord(编译器也会告诉你同样的)。你写它的方式,T也需要实现Copy,但它可以被修改,所以T需要Clone。如果您将此作为学习练习,请继续,但这就像使用处理器在 C++ 中实现泛型一样。你可以这样做,但它没有意义。
标签: rust rust-macros rust-decl-macros