Learning the language structure and design concepts

Coming from a more python javascript entry, struggling with the rust compiler errors has been teaching me a lot of the things that I thought I understood about c and c ++. Anyways, pardon the crude code but I'm just trying to get a comprehension of the design concepts, my OOP level of thinking is still based on dynamic language habits. One thing I'm trying to figure out is how to take two or more entities and enter them into a process (such as a combat situation in a video game), and then return back to the idle scope. From what I've read this can be done for a single entity by assigning a variable to the output of that process, and then returning the ownership to the variable (main scope) once the process finishes. I wasn't able to commit two (or more) entities to a process though, by attempting to assign multiple variables at once with a comma: (partial early code)

fn sim_battle(ent1:entity, ent2:entity) -> (entity, entity) {
     //combat sim
    (ent1, ent2)
entity1, entity2 = sim_battle(entity1,entity2);

...but that didn't work, or variations of it. So instead I put all entities on screen into an array, and then passed the array's ownership to the process instead, but now I'm thinking this will cause all other entities in the room that aren't engaged in the process to also be locked ownership until the process returns. In general though I wanted to see if this was more or less the right direction, as sometimes it feels like I'm just building "around" the compiler instead of designing, but that could also be testament to my poorly learned programming habits :stuck_out_tongue: . Anyways, here's the example that compiles and runs as intended. In particular, the passing of the array into the function, as well as the .clone() method for the entity struct, are the parts that I'm questioning and trying to re-design: (full current code)

fn main() {

    let mut player: entity = entity {hp: 100, att_power: 20, roster: 0};
    let mut player2: entity = entity {hp: 100, att_power: 20, roster: 1};

    let mut room:[entity; 2] = [player, player2];

    println!("{}", room[0].hp());
    println!("{}", room[1].hp());

    room = sim_battle(room, 0, 1);



fn sim_battle(room:[entity; 2], player1:usize, player2:usize) -> [entity; 2] {

    let mut ent1 = room[player1].clone();
    let mut ent2 = room[player2].clone();

    ent1.hp_mut(ent1.hp() - ent2.att_power());
    ent2.hp_mut(ent2.hp() - ent1.att_power());

    let room2 = [ent1, ent2];

struct entity {

    hp: u16,
    att_power: u16,
    roster: usize,

impl entity {

    fn clone(&self) -> Self {
        Self{hp:self.hp, att_power:self.att_power, roster:self.roster}
    fn hp(&self) -> u16 {
    fn att_power(&self) -> u16 {
    fn roster(&self) -> usize {

    fn hp_mut(&mut self, hp:u16) {
        self.hp = hp;


Did you try let (entity1, entity2) = sim_battle(entity1, entity2); ?

I recommend running cargo fmt and cargo clippy (and fixing any clippy errors) on your code to follow common conventions to make it easier to read. Most important of the things clippy will complain about in this case is that struct names should be in CamelCase, in this case struct Entity.

I did try that too, but still got a compile error

edit: Thanks I will look into the clippy and fmt though,

I was going to just work up an example of a function that returns a tuple and how you can use that, but ended up doing a more thorough review. Most of the comments probably should have been made inline here in the forum, but I've already written them as comments in the code. Anyway, you can see them in the playground. Hopefully it's useful.

1 Like

Thank you very much, I had a bit of a facepalm moment when I saw you pass the entity as a mutable reference, why didn't I think of that when I was writing the hp functions, lol. Awesome, I'll look over this during tomorrow's coffee and consider those options. Cheers!

1 Like