Operate on objects individually and in a collection


#1

Hi there,

I’ve been playing around with Rust for a while now and I’m trying to write a sort of simple modular game engine. Basically, I want to be able to do something like this:

struct TaskA;
impl TaskA {
    pub fn mutate(&mut self) { ... }
    ...
}

struct TaskB;
impl TaskB {
    pub fn mutate_differently(&mut self) { ... }
    ...
}

trait Task {
    pub fn report_task_info(&self) { ... }
    ...
}

impl Task for TaskA { ... }
impl Task for TaskB { ... }

fn main() {
    let mut task_a = TaskA;
    let mut task_b = TaskB;
    let tasks = vec![&task_a, &task_b];
    
    loop {
        {
            // Can't do this!! The tasks have been borrowed already.
            task_a.mutate();
            task_b.mutate_differently();
        }
        
        for task in tasks {
            task.report_task_info();
        }
    }
}

So I want to operate on each task individually at some points of the main loop, but at other points, I want to do the same task on all of them. In most other languages, this would work fine. Conceptually, I think it’s sound as well, as long as the tasks variable is not accessed while the tasks are mutably borrowed.

My question is, is there a way to do this kind of thing in safe Rust. Or better yet, is there a more Rust-y way of accomplishing the same thing?

Thanks, and I hope this makes sense.


#2

This issue can be solved by constructing the tasks reference list only when it’s needed instead of storing it for the duration of the loop:

for task in &[&task_a, &task_b] { ... }

The borrow checker doesn’t allow you to have a mutable reference to an object if there is a reference to this object elsewhere.