Rust - BTreeMap没有正确更新vector in value



我在使用BTreeMaps时遇到了一个问题;它们似乎不会在程序运行时更新。下面是一个例子:

fn monke_do_monke_bisnis(mut monkes: BTreeMap<i32, Monke>) -> BTreeMap<i32, Monke> {
for mut monke in monkes.to_owned() {
println!("Monkey: {:?}", monke.0);
let mut new_prio: f32 = 0.0;
for i in monke.1.inventory.to_owned() {
println!("Inventory length: {:?}", monke.1.inventory.len());
println!("Inspected item: {:?}", i);
let last = parse_last(i, monke.1.operation.last.clone());
match monke.1.operation.operand {
'*' => {
new_prio = ((i * last)) as f32
}
'/' => {
new_prio = ((i / last)) as f32
}
'+' => {
new_prio = ((i + last)) as f32
}
'-' => {
new_prio = ((i - last)) as f32
}
_ => panic!("need op bruv"),
}
println!("New worry level of item: {:?}", new_prio);

new_prio /= 3.0;
new_prio = new_prio.floor();
println!("New worry level of item / 3: {:?}", new_prio);

if (new_prio as i32) % monke.1.test == 0 {
monkes.entry(monke.1.true_outcome).and_modify(|monk| {
monk.inventory.push(new_prio as i32);
println!("TRUE: Thrown to: {:?}", monk.id);                    
println!("Inventory of {:?}: {:?}", monk.id, monk.inventory);
});
} else {
monkes.entry(monke.1.false_outcome).and_modify(|monk| {
monk.inventory.push(new_prio as i32);     
println!("FALSE: Thrown to: {:?}", monk.id);
println!("Inventory of {:?}: {:?}", monk.id, monk.inventory);
});
}
//remove item from original monke
monkes
.entry(monke.1.id)
.and_modify(|monk| {
monk.inventory.remove(0);
monk.inspect_count += 1;
});
}
}
return monkes;
}

结构体如下:


#[derive(Default, Debug, Clone)]
struct Monke {
id: i32,
inventory: Vec<i32>,
operation: Operation,
test: i32,
true_outcome: i32,
false_outcome: i32,
inspect_count: i32,
}
#[derive(Default, Debug, Clone)]
struct Operation {
operand: char,
last: String,
}

下面是让它运行时的控制台输出:

Monke { id: 0, inventory: [20, 23, 27, 26], operation: Operation { operand: '*', last: "19" }, test: 23, true_outcome: 2, false_outcome: 3, inspect_count: 2 }
Monke { id: 1, inventory: [25], operation: Operation { operand: '+', last: "6" }, test: 19, true_outcome: 2, false_outcome: 0, inspect_count: 4 }
Monke { id: 2, inventory: [], operation: Operation { operand: '*', last: "old" }, test: 13, true_outcome: 1, false_outcome: 3, inspect_count: 3 }
Monke { id: 3, inventory: [500, 620, 1200, 3136], operation: Operation { operand: '+', last: "3" }, test: 17, true_outcome: 0, false_outcome: 1, inspect_count: 1 }

输出应该是这样的:

Monke { id: 0, inventory: [20, 23, 27, 26], operation: Operation { operand: '*', last: "19" }, test: 23, true_outcome: 2, false_outcome: 3, inspect_count: 2 }
Monke { id: 1, inventory: [2080, 25, 167, 207, 401, 1046], operation: Operation { operand: '+', last: "6" }, test: 19, true_outcome: 2, false_outcome: 0, inspect_count: 4 }
Monke { id: 2, inventory: [], operation: Operation { operand: '*', last: "old" }, test: 13, true_outcome: 1, false_outcome: 3, inspect_count: 3 }
Monke { id: 3, inventory: [], operation: Operation { operand: '+', last: "3" }, test: 17, true_outcome: 0, false_outcome: 1, inspect_count: 1 }

似乎我正在使用的BTreeMap没有被正确更新,因为逻辑是正确的。这可能是什么原因呢?

您在函数的开头克隆monkes(通过to_owned()),并迭代该对象而不是原始对象。在以后的循环迭代中,当需要Monkey 1时,仍然要从克隆映射中读取它的原始值。您正在使用的条目模式可能很难使工作,因为您需要同时修改集合中的多个项目,但我不知道使用您拥有的映射的最佳解决方案(我会使用Vec,因为索引可以对应于id)。

最新更新