Rust 如何实现定义新公共类型并返回该类型实例的宏?
我想用Rust 如何实现定义新公共类型并返回该类型实例的宏?,rust,rust-macros,rust-decl-macros,Rust,Rust Macros,Rust Decl Macros,我想用macro\u规则实现一个结构{ //定义结构 Ytz酒店结构{ 表:hashbrown::hash_map::HashMap, } impl Ytz{ pub fn new()->Self{ Ytz{ 表:hashbrown::hash_map::HashMap:::new(), } } 发布fn添加(&mut self,项目:&T美元){ 如果self.table.包含_键(项){ *self.table.get_mut(item).unwrap()+=*item; }否则{ self
macro\u规则实现一个结构因为泛型需要大量的样板和特征搜索
所讨论的结构内部有一个哈希表,但键和值类型将由用户提供。代码如下:
macro\u规则!纽伊茨{
($T:ty)=>{
//定义结构
Ytz酒店结构{
表:hashbrown::hash_map::HashMap,
}
impl Ytz{
pub fn new()->Self{
Ytz{
表:hashbrown::hash_map::HashMap:::new(),
}
}
发布fn添加(&mut self,项目:&T美元){
如果self.table.包含_键(项){
*self.table.get_mut(item).unwrap()+=*item;
}否则{
self.table.insert(*项目,*项目);
}
}
酒吧fn最大的(和自身)->吨{
设mut result=0;
对于self.table.values()中的v{
如果结果<*v{
结果=*v;
}
}
结果
}
}
//构造结构的实例并返回它
Ytz::new()
};
}
//驱动程序
fn main(){
让mut y=new_ytz!(u64);//应该构造对象并返回ytz::new()
y、 添加(&71);
y、 添加(&25);
y、 添加(&25);
y、 添加(&25);
y、 添加(&34);
println!(“{}”,y.max());
}
这将不会编译,因为它试图将结构粘贴到主函数中:
错误:应为表达式,找到关键字`pub`
-->src/main.rs:4:9
|
4 |年初至今的酒吧结构{
|^^^所需的表达式
...
40 |让mut y=new_ytz!(u64);//应该构造对象并返回ytz::new()
|------在此宏调用中
如何解决它?如何将结构与impl
块一起公开粘贴到主函数之外
泛型需要大量的样板
使用std::collections::HashMap;
使用core::hash::hash;
使用std::ops::AddAssign;
结构YtzU64{
表:HashMap
}
impl YtzU64{
pub fn new()->Self{
自我{
表:HashMap::new()
}
}
发布fn添加(&mut self,项:&T){
如果让某些(项目)=self.table.get_mut(项目){
*项目+=*项目;
}否则{
self.table.insert(*项目,*项目);
}
}
pub fn最大(&self)->选项{
让mut values=self.table.values();
让mut最大:Option=values.next().map(| t |*t);
对于v值{
如果最大值小于某些值(*v){
最大=一些(*v);
}
}
最大的
}
}
fn main(){
让mut y=YtzU64::new();
y、 添加(&71);
y、 添加(&25);
y、 添加(&25);
y、 添加(&25);
y、 添加(&34);
println!(“{}”,y.max().unwrap());
}
我翻译你的宏所需要的样板文件比你的宏少。它的缩进少了两个,行数少了4行(macro_rules!),顶部有模式匹配,末尾有两个大括号)。请注意,我稍微更改了api,因为maxist
现在返回一个选项,以匹配std::iter::Iterator::max()
。还要注意,您的api设计仅限于T:Copy
。如果您想支持T:?Copy+Clone
或T:?Copy+?Clone
,则必须对其进行重新设计
性状搜寻
编译器是你的朋友。看看当我删除一个特征边界时会发生什么
error[E0277]: the trait bound `T: std::hash::Hash` is not satisfied
...
使用宏是一个有趣的练习,但使用宏重新实现泛型是没有用的。你不能这样做。为什么要让生活变得复杂?因为寻找特征很困难。例如,要概括这一点,我必须手动查找许多不同类型的特征,以及大量编译/失败/查找宏/添加特征等。这()看起来很难看,但现在它可以完成任务。你说的特征搜索是什么意思?我可以不看Rust的文档就告诉你,T
需要实现Hash
、Eq
和Ord
(编译器也可以告诉你同样的情况)你写的方式, T也需要实现拷贝< /C>,但是可以修改,<>代码> t>代码>需要代码>克隆< /COD>。如果你把它作为学习练习,那么,就好像使用处理器来实现C++中的泛型。你可以做到,但它没有意义。技术上,部分如果您不关心total ordering属性,Ord也应该在这里工作。