我有一系列国家,我希望产生这些国家之间的关系,因此国家A和国家B之间的关系总是与国家B和国家A之间的关系相同。
例如,日本和厄瓜多尔的关系值为15.我希望能够同时运行get_relationship("Japan", "Ecuador");
和get_relationship("Ecuador", "Japan");
并始终获得15
。理想情况下,我不想两次存储此值,因为我不想让它保持同步。
以下是我目前的实验代码。请注意,由于无关原因,我将国家/地区存储为HashMap
(name as String, Nation as struct)
,主要是因为我可以仅通过名称提取所需的Nation
对象。
extern crate rand;
use std::collections::HashMap;
use rand::Rng;
struct Nation;
pub struct NationManager {
nations: HashMap<String, Nation>, // The string is the nation's name
rels: HashMap<String, HashMap<String, i8>>, // Again, both Strings are names
}
impl NationManager {
fn generate_relationships(&mut self) {
let mut random_rel: i8 = rand::thread_rng().gen_range(1, 101);
for (source, _) in &self.nations {
for (target, _) in &self.nations {
if source > target {
self.rels
.get(source)
.expect("ERROR")
.insert(target.clone(), random_rel);
} else if source < target {
self.rels
.get(target)
.expect("ERROR")
.insert(source.clone(), random_rel);
} else {
continue;
}
}
}
}
}
fn main() {}
我不认为这是达到预期结果的最佳方式,而且目前还没有编译;实际上可以像这样嵌套两个for
循环吗?
error: cannot borrow immutable borrowed content as mutable
--> src/main.rs:19:21
|
19 | self.rels
| _____________________^ starting here...
20 | | .get(source)
21 | | .expect("ERROR")
| |________________________________________^ ...ending here: cannot borrow as mutable
error: cannot borrow immutable borrowed content as mutable
--> src/main.rs:24:21
|
24 | self.rels
| _____________________^ starting here...
25 | | .get(target)
26 | | .expect("ERROR")
| |________________________________________^ ...ending here: cannot borrow as mutable
答案 0 :(得分:5)
首先要做的事情是:您遇到的问题是get
会返回一个不可变引用,并且您会尝试insert
。您可能希望使用get_mut
获取可执行insert
的可变引用。
但我建议改变设计:
这种方案的主要优点是数字ID比字符串便宜/高效。
pub struct NationManager {
last_id: u32,
name_to_id: HashMap<String, u32>,
relationships: HashMap<(u32, u32), i8>, // (smaller ID, larger ID) -> score
}
查看两个国家/地区之间的关系将涉及了解他们的ID(name_to_id
中的两个查找),然后查找关系分数。
relationships
的扁平化将极大地 简化了你的生成步骤:
impl NationManager {
fn generate_relationships(&mut self) {
let random_rel: i8 = rand::thread_rng().gen_range(1, 101);
for source in 0..self.last_id {
for target in (source + 1)..self.last_id {
self.relationships.insert((source, target), random_rel);
}
}
}
}
注意:实际上,域分析可以让我们使用更小的ID;你不应该超过65,535个国家,所以u16
肯定是足够的,并且u8
(255个国家)也足够(有193个国家)在联合国登记。
答案 1 :(得分:1)
问题是你使用的是错误的方法。 HashMap::get
不允许您改变结果:
fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where K: Borrow<Q>,
Q: Hash + Eq,
您想要get_mut
:
fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
where K: Borrow<Q>,
Q: Hash + Eq,