1

I have a problem where I create an object containing a vector of objects:

pub struct ParticleSystem {
    particles: Vec<Particle>
}

impl ParticleSystem {
    pub fn new() -> ParticleSystem {
        ParticleSystem {
            particles: Vec::new()
        }
    }
}

I need to be able to access the vector within this object from within a function in the Particle class without passing ownership.

let mut system = ParticleSystem::new();

How would I go about passing a pointer to this through to the function? I'm quite new to rust. Thank you for your help, when i've tried it just passes ownership and interferes with other aspects of the program.

ImTryingOK
  • 11
  • 2
  • Does this answer your question? [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct) – Jmb Mar 25 '21 at 09:09
  • Thanks for the suggestion, but i'm not looking to store anything, i'm just needing a way to access the position variables of all other particles in the system to check if a collision has occured. – ImTryingOK Mar 25 '21 at 09:21
  • _"I need to be able to access the vector within this object from within a function in the Particle clas"_ -- which function? Need more info to answer this question. – Peter Hall Mar 25 '21 at 09:24
  • The particle struct contains a function for checking for collisions. But in order to check that I need to be able check the positions of all other particles in the ParticleSystem, I was hoping for a way to pass some kind of pointer to the particle system as a parameter without passing ownership of the particle system itself. – ImTryingOK Mar 25 '21 at 09:28
  • It would help to include some example code: what you tried and what didn't work about it. – Peter Hall Mar 25 '21 at 10:46

1 Answers1

1

If you need to compare one Particle with every other Particle in the ParticleSystem you can pass a reference to the other Particles as an argument:

impl Particle {
    pub fn has_collision(&self, others: &[Particle]) -> bool {
        for other in others {
            if other.dist(self) < threshold {
                return true;
            }
        }
        false
    }
}

This is much simpler than each Particle having its own reference to the entire system, because the borrow only lasts as long as the call to the function. If the Particle had a field which is a reference to the entire system then this gets more complicated because Rust needs to be sure that each Particle cannot outlive the entire system - which would require a lot of work and probably runtime overhead; for example, when you destroy the system you would need to make sure that every Particle is dropped before the ParticleSystem is dropped.

Also, it's more memory-efficient this way because the Particle struct doesn't need to include a pointer to the system.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204