gpt4 book ai didi

rust - 在惯用 Rust 中实现容器元素关系的正确方法

转载 作者:行者123 更新时间:2023-11-29 08:21:08 24 4
gpt4 key购买 nike

我知道为什么 Rust 不喜欢我的代码。但是,我不知道什么是惯用的 Rust 方法来解决这个问题。

我是一名 C# 程序员,虽然我觉得我理解 Rust 的系统,但我认为我对某些问题的“旧”方法在 Rust 中根本不起作用。

这段代码重现了我遇到的问题,它可能看起来不像惯用的 Rust(或者它甚至在 C# 中看起来也不太好):

//a "global" container for the elements and some extra data
struct Container {
elements: Vec<Element>,
global_contextual_data: i32,
//... more contextual data fields
}

impl Container {
//this just calculates whatever I need based on the contextual data
fn calculate_contextual_data(&self) -> i32 {
//This function will end up using the elements vector and the other fields as well,
//and will do some wacky maths with it.
//That's why I currently have the elements stored in the container
}
}

struct Element {
element_data: i32,
//other fields
}

impl Element {
//I need to take a mutable reference to update element_data,
//and a reference to the container to calculate something that needs
//this global contextual data... including the other elements, as previously stated
fn update_element_data(&mut self, some_data: i32, container: &Container) {
self.element_data *= some_data + container.calculate_contextual_data() //do whatever maths I need
}
}


fn main(){

//let it be mutable so I can assign the elements later
let mut container = Container {
elements: vec![],
global_contextual_data: 1
};

//build a vector of elements
let elements = vec![
Element {
element_data: 5
},
Element {
element_data: 7
}
];

//this works
container.elements = elements;

//and this works, but container is now borrowed as mutable
for elem in container.elements.iter_mut() {
elem.element_data += 1; //and while this works
let some_data = 2;

//i can't borrow it as immutable here and pass to the other function
elem.update_element_data(some_data, &container);
}
}

我明白为什么 elem.update_element_data(some_data, &container); 不起作用:当我调用 iter_mut 时,我已经将它借用为可变的。也许每个元素都应该引用容器?但是这样我岂不是有更多机会打破借贷检查?

我认为不可能将我的旧方法应用到这个新系统中。也许我需要重写整个事情。有人能指出我正确的方向吗?我刚开始用 Rust 编程,虽然所有权系统对我来说有点意义,但我应该“围绕”它编写的代码仍然不是那么清楚。

最佳答案

我遇到了这个问题: What's the Rust way to modify a structure within nested loops?这让我深入了解了我的问题。

我重新审视了这个问题,并将问题归结为通过同时借用写入和读取来共享向量。这是 Rust 所禁止的。我不想使用 unsafe 来规避借用检查器。不过,我想知道我应该复制多少数据?

我的 Element,实际上是游戏的实体(我正在模拟唱首歌游戏)具有可变和不可变的属性,我将它们分开。

struct Entity {
type: EntityType,
starting_price: f64,
...
...
status: Cell<EntityStatus>
}

每次我需要更改实体的状态时,我都需要在status 字段上调用getset 方法。 EntityStatus 派生 Clone, Copy

我什至可以将字段直接放在结构上,让它们都是 Cell,但这样使用它们会很麻烦(很多调用 getset),所以我选择了更美观的方法。

通过允许自己复制status、编辑和设置它,我可以不可变地借用数组两次(.iter()而不是 .iter_mut())。

我担心因为复制会导致性能变差,但实际上我用opt-level=3 编译后就很好了。如果出现问题,我可能会将字段更改为 Cell 或想出另一种方法。

关于rust - 在惯用 Rust 中实现容器元素关系的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44607467/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com