Rust 为什么即使我';m传入一个可以取消引用并添加的类型?

Rust 为什么即使我';m传入一个可以取消引用并添加的类型?,rust,Rust,我对方法的一般实现有一些问题: use std::collections::BTreeMap; use global::entity::EntityId; struct simple_system<T> { list_sum: BTreeMap<EntityId, T>, list_com: BTreeMap<EntityId, Vec<T>>, } impl<T> simple_system<T> {

我对方法的一般实现有一些问题:

use std::collections::BTreeMap;
use global::entity::EntityId;

struct simple_system<T> {
    list_sum: BTreeMap<EntityId, T>,
    list_com: BTreeMap<EntityId, Vec<T>>,
}

impl<T> simple_system<T> {
    pub fn new() -> simple_system<T> {
        simple_system {
            list_sum: BTreeMap::new(),
            list_com: BTreeMap::new(),
        }
    }

    pub fn addComponent(&mut self, id: EntityId, comp: T) {
        self.list_com.entry(id).or_insert_with(Vec::new).push(comp);
        match self.list_sum.get_mut(&id) {
            Some(v) => *v = *v + *comp,
            None => self.list_sum.insert(id, comp),
        }
    }
}

我不知道我必须改变什么才能让它工作。我使用它,代码 u32 类型,所以它应该有一个<代码> +>代码>运算符。

< p>锈泛型系统不能像C++模板那样工作:在C++中,编译器不检查代码是否预先编译成任何类型。 Rust确保函数编译时使用满足所列要求的任何类型(调用)。编译器已经告诉您缺少的内容:
std::ops::Add
可能缺少
T
,因此请询问:

impl<T: Add<Output = T>> simple_system<T> { /* … */ }
impl simple_system{/*…*/}

这并不能解决所有问题;你的代码还有其他问题。

< P>锈泛型系统不能像C++模板那样工作:在C++中,编译器不检查代码是否预先编译成任何类型。 Rust确保函数编译时使用满足所列要求的任何类型(调用)。编译器已经告诉您缺少的内容:
std::ops::Add
可能缺少
T
,因此请询问:

impl<T: Add<Output = T>> simple_system<T> { /* … */ }
impl simple_system{/*…*/}
这并不能解决所有问题;您的代码还存在其他问题。

解决方案如下:

  • 首先,您应该编写一个工作的非通用(c++模板)版本,然后将其发展为通用版本

    use std::collections::BTreeMap;
    
    #[derive(Debug)]
    struct SumUpSystem {
        list_sum: BTreeMap<u64, i32 >,
        list_com: BTreeMap<u64, Vec<i32> >
    }
    
    impl SumUpSystem {
        pub fn new() -> SumUpSystem {
            SumUpSystem {
                list_sum: BTreeMap::new(),
                list_com: BTreeMap::new()
            }
        }
    
        pub fn add_component(&mut self, id: u64, comp: i32) {
            self.list_com.entry(id).or_insert_with(Vec::new).push(comp);
    
            let mut insert = false;
            match self.list_sum.get_mut(&id) {
                Some(x) => *x = *x + comp,
                None => insert = true
            }
    
            if (insert) {
                self.list_sum.insert(id, comp);
            }
        }
    
        pub fn sum(& self, id: u64) -> i32 {
            if let Some(x) = self.list_sum.get(&id) {
                *x
            } else {
                panic!("Invalid id: Not in system!");
            }
        }
    }
    
    #[cfg(test)]
    mod test {
        use super::*;
    
        macro_rules! init_test {
            ($v:ident) => (let mut $v : SumUpSystem = SumUpSystem::new(););
        }
    
        #[test]
        fn add_component() {
            init_test!(s);
            s.add_component(1, 13);
            assert_eq!(s.sum(1), 13);
            s.add_component(1, 26);
            assert_eq!(s.sum(1), 13 + 26);
        }
    }
    
    使用std::collections::BTreeMap;
    #[导出(调试)]
    结构汇总系统{
    列表汇总:BTreeMap,
    列表com:BTreeMap
    }
    impl SUMUPS系统{
    pub fn new()->SumUpSystem{
    综合系统{
    list_sum:BTreeMap::new(),
    list_com:BTreeMap::new()
    }
    }
    发布fn添加组件(&mut self,id:u64,comp:i32){
    self.list\u com.entry(id).或使用(Vec::new.push)(comp)插入\u;
    让mut insert=false;
    匹配self.list\u sum.get\u mut(&id){
    一些(x)=>*x=*x+comp,
    无=>insert=true
    }
    如果(插入){
    自我列表和插入(id、公司);
    }
    }
    发布fn sum(&self,id:u64)->i32{
    if let Some(x)=self.list\u sum.get(&id){
    *x
    }否则{
    惊慌失措!(“无效id:不在系统中!”);
    }
    }
    }
    #[cfg(测试)]
    模试验{
    使用超级::*;
    宏规则!初始测试{
    ($v:ident)=>(让mut$v:SumUpSystem=SumUpSystem::new(););
    }
    #[测试]
    fn添加_组件(){
    初始测试!(s);
    s、 增加_分量(1,13);
    断言(s.sum(1),13);
    s、 增加_分量(1,26);
    断言(s.sum(1),13+26);
    }
    }
    
  • 通用(c++模板)。您应该阅读Rust文档的特征部分,以了解其工作原理

    use std::collections::BTreeMap;
    use std::ops::Add;
    
    #[derive(Debug)]
    struct SumUpSystem<T> {
        list_sum: BTreeMap<u64, T >,
        list_com: BTreeMap<u64, Vec<T> >
    }
    
    impl <T: Add<Output=T> + Clone> SumUpSystem<T> {
        pub fn new() -> SumUpSystem<T> {
            SumUpSystem {
                list_sum: BTreeMap::new(),
                list_com: BTreeMap::new()
            }
        }
    
        pub fn add_component(&mut self, id: u64, comp: &T) {
            self.list_com.entry(id).or_insert_with(Vec::new).push(comp.clone());
    
            let mut insert = false;
            match self.list_sum.get_mut(&id) {
                Some(x) => *x = x.clone() + comp.clone(),
                None => insert = true
            }
    
            if insert {
                self.list_sum.insert(id, comp.clone());
            }
        }
    
        pub fn sum(& self, id: u64) -> T {
            if let Some(x) = self.list_sum.get(&id) {
                x.clone()
            } else {
                panic!("Invalid id: Not in system!");
            }
        }
    }
    
    #[cfg(test)]
    mod test {
        use super::*;
    
        macro_rules! init_test {
            ($v:ident) => (let mut $v : SumUpSystem<i32> = SumUpSystem::new(););
        }
    
        #[test]
        fn add_component() {
            init_test!(s);
            s.add_component(1, &13i32);
            assert_eq!(s.sum(1), 13i32);
            s.add_component(1, &26i32);
            assert_eq!(s.sum(1), 39i32);
        }
    }
    
    使用std::collections::BTreeMap;
    使用std::ops::Add;
    #[导出(调试)]
    结构汇总系统{
    列表汇总:BTreeMap,
    列表com:BTreeMap
    }
    impl SUMUPS系统{
    pub fn new()->SumUpSystem{
    综合系统{
    list_sum:BTreeMap::new(),
    list_com:BTreeMap::new()
    }
    }
    发布fn添加组件(&mut self,id:u64,comp:&T){
    self.list\u com.entry(id).或插入带有(Vec::new).push(comp.clone())的元素;
    让mut insert=false;
    匹配self.list\u sum.get\u mut(&id){
    某些(x)=>*x=x.clone()+复合克隆(),
    无=>insert=true
    }
    如果插入{
    self.list_sum.insert(id,comp.clone());
    }
    }
    发布fn sum(&self,id:u64)->T{
    if let Some(x)=self.list\u sum.get(&id){
    x、 克隆()
    }否则{
    惊慌失措!(“无效id:不在系统中!”);
    }
    }
    }
    #[cfg(测试)]
    模试验{
    使用超级::*;
    宏规则!初始测试{
    ($v:ident)=>(让mut$v:SumUpSystem=SumUpSystem::new(););
    }
    #[测试]
    fn添加_组件(){
    初始测试!(s);
    s、 添加_组件(1和13i32);
    断言(s.sum(1),13i32);
    s、 添加_组件(1和26i32);
    断言(s.sum(1),39i32);
    }
    }
    
  • 这里是解决方案:

  • 首先,您应该编写一个工作的非通用(c++模板)版本,然后将其发展为通用版本

    use std::collections::BTreeMap;
    
    #[derive(Debug)]
    struct SumUpSystem {
        list_sum: BTreeMap<u64, i32 >,
        list_com: BTreeMap<u64, Vec<i32> >
    }
    
    impl SumUpSystem {
        pub fn new() -> SumUpSystem {
            SumUpSystem {
                list_sum: BTreeMap::new(),
                list_com: BTreeMap::new()
            }
        }
    
        pub fn add_component(&mut self, id: u64, comp: i32) {
            self.list_com.entry(id).or_insert_with(Vec::new).push(comp);
    
            let mut insert = false;
            match self.list_sum.get_mut(&id) {
                Some(x) => *x = *x + comp,
                None => insert = true
            }
    
            if (insert) {
                self.list_sum.insert(id, comp);
            }
        }
    
        pub fn sum(& self, id: u64) -> i32 {
            if let Some(x) = self.list_sum.get(&id) {
                *x
            } else {
                panic!("Invalid id: Not in system!");
            }
        }
    }
    
    #[cfg(test)]
    mod test {
        use super::*;
    
        macro_rules! init_test {
            ($v:ident) => (let mut $v : SumUpSystem = SumUpSystem::new(););
        }
    
        #[test]
        fn add_component() {
            init_test!(s);
            s.add_component(1, 13);
            assert_eq!(s.sum(1), 13);
            s.add_component(1, 26);
            assert_eq!(s.sum(1), 13 + 26);
        }
    }
    
    使用std::collections::BTreeMap;
    #[导出(调试)]
    结构汇总系统{
    列表汇总:BTreeMap,
    列表com:BTreeMap
    }
    impl SUMUPS系统{
    pub fn new()->SumUpSystem{
    综合系统{
    list_sum:BTreeMap::new(),
    list_com:BTreeMap::new()
    }
    }
    发布fn添加组件(&mut self,id:u64,comp:i32){
    self.list\u com.entry(id).或使用(Vec::new.push)(comp)插入\u;
    让mut insert=false;
    匹配self.list\u sum.get\u mut(&id){
    一些(x)=>*x=*x+comp,
    无=>insert=true
    }
    如果(插入){
    自我列表和插入(id、公司);
    }
    }
    发布fn sum(&self,id:u64)->i32{
    if let Some(x)=self.list\u sum.get(&id){
    *x
    }否则{
    惊慌失措!(“无效id:不在系统中!”);
    }
    }
    }
    #[cfg(测试)]
    模试验{
    使用超级::*;
    宏规则!初始测试{
    ($v:ident)=>(让mut$v:SumUpSystem=SumUpSystem::new(););
    }
    #[测试]
    fn添加_组件(){
    初始测试!(s);
    s、 增加_分量(1,13);
    断言(s.sum(1),13);
    s、 增加_分量(1,26);
    断言(s.sum(1),13+26);
    }
    }
    
  • 通用(c++模板)。您应该阅读Rust文档的特征部分,以了解其工作原理

    use std::collections::BTreeMap;
    use std::ops::Add;
    
    #[derive(Debug)]
    struct SumUpSystem<T> {
        list_sum: BTreeMap<u64, T >,
        list_com: BTreeMap<u64, Vec<T> >
    }
    
    impl <T: Add<Output=T> + Clone> SumUpSystem<T> {
        pub fn new() -> SumUpSystem<T> {
            SumUpSystem {
                list_sum: BTreeMap::new(),
                list_com: BTreeMap::new()
            }
        }
    
        pub fn add_component(&mut self, id: u64, comp: &T) {
            self.list_com.entry(id).or_insert_with(Vec::new).push(comp.clone());
    
            let mut insert = false;
            match self.list_sum.get_mut(&id) {
                Some(x) => *x = x.clone() + comp.clone(),
                None => insert = true
            }
    
            if insert {
                self.list_sum.insert(id, comp.clone());
            }
        }
    
        pub fn sum(& self, id: u64) -> T {
            if let Some(x) = self.list_sum.get(&id) {
                x.clone()
            } else {
                panic!("Invalid id: Not in system!");
            }
        }
    }
    
    #[cfg(test)]
    mod test {
        use super::*;
    
        macro_rules! init_test {
            ($v:ident) => (let mut $v : SumUpSystem<i32> = SumUpSystem::new(););
        }
    
        #[test]
        fn add_component() {
            init_test!(s);
            s.add_component(1, &13i32);
            assert_eq!(s.sum(1), 13i32);
            s.add_component(1, &26i32);
            assert_eq!(s.sum(1), 39i32);
        }
    }
    
    使用std::collections::BTreeMap;
    使用std::ops::Add;
    #[导出(调试)]
    结构汇总系统{
    列表汇总:BTreeMap,
    列表com:BTreeMap
    }
    impl SUMUPS系统{
    pub fn new()->SumUpSystem{
    综合系统{
    list_sum:BTreeMap::new(),
    list_com:BTreeMap::new()
    }
    }
    pub fn add_组件(