如何从函数返回一个分支后修改借用的HashMap?

时间:2017-08-16 15:02:49

标签: hashmap rust borrow-checker borrowing

我尝试简化程序,但如果我使用简单的HashMap<u16, u16>而不是嵌套的HashMap Polynome类,则没有错误。

您将需要这些导入来重现问题:

use std::collections::{HashMap, BTreeMap};
use std::hash::{Hash, Hasher};

这些是我的类型:

pub struct VarIdx(pub BTreeMap<u16, u8>);
pub type Polynome = HashMap<VarIdx, f64>;

这是我需要使嵌套HashMap工作的东西:

impl PartialEq for VarIdx {
    fn eq(&self, other: &VarIdx) -> bool {
        if self.0 == other.0 {
            return true;
        }
        if self.0.len() != other.0.len() {
            return false;
        }
        for (k, v) in self.0.iter() {
            match other.0.get(k) {
                Some(v1) => {
                    if v != v1 {
                        return false;
                    }
                }
                None => {}
            }

        }
        (true)
    }
}
impl Eq for VarIdx {}
impl VarIdx {
    pub fn len(&self) -> usize {
        return self.0.len();
    }
}
impl Hash for VarIdx {
    fn hash<H>(&self, _state: &mut H)
    where
        H: Hasher,
    {
        for (k, v) in self.0.iter() {
            k.hash(_state);
            v.hash(_state);
        }
    }
}

我有这个功能来找到第一个合理的密钥:

fn get_first_product(poly: &Polynome) -> Option<&VarIdx> {
    for (key, coeff) in poly {
        if key.len() < 2 {
            return None;
        }
        return Some(key);
    }
    None
}

我想调用此函数并根据返回的键执行一些操作,为简单起见,我想从HashMap中删除此键:

fn reduce_product(poly: &mut Polynome) -> bool {
    let key = {
        let res = get_first_product(poly);
        if res == None {
            return false;
        }
        res.unwrap()
    };
    poly.remove(&key);
    true
}

这不会编译,因为poly借用get_first_product而无法重新借用:

error[E0502]: cannot borrow `*poly` as mutable because it is also borrowed as immutable
  --> src/main.rs:64:5
   |
60 |         let res = get_first_product(poly);
   |                                     ---- immutable borrow occurs here
...
64 |     poly.remove(&key);
   |     ^^^^ mutable borrow occurs here
65 |     true
66 | }
   | - immutable borrow ends here

如何解决这个基本任务?在将.clone()传递给poly之前,我尝试get_first_product(),但我收到了另一条错误消息:

error[E0599]: no method named `clone` found for type `&mut std::collections::HashMap<VarIdx, f64>` in the current scope
  --> src/main.rs:65:42
   |
65 |         let res = get_first_product(poly.clone());
   |                                          ^^^^^
   |
   = note: the method `clone` exists but the following trait bounds were not satisfied:
           `VarIdx : std::clone::Clone`

我为.clone()实施了VarIdx

处理此类案件的推荐方法是什么?我想避免.clone有一个有效的计划。

这似乎与this question不重复,因为如果我尝试使用非嵌套的HashMap而不是Polynome,代码编译得很好:

fn get_first_product_nonnested(poly: &HashMap<u16, u16>) -> Option<u16> {
    for (key, coeff) in poly {
        if coeff>&2 {
            return None;
        }
        return Some(*key);
    }
    None
}
fn reduce_product_nonnested(poly: &mut HashMap<u16,u16>) -> bool {
    let key = {
        let res = get_first_product_nonnested(poly);
        if res == None { return false; }
        res.unwrap()
    };
    poly.remove(&key);
    true
}

所以有一些东西,这使得我的Polynome类型与HashMap不同。

0 个答案:

没有答案