Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot move out of borrowed content in Rust

Tags:

rust

pub struct Character {
    name: String,
    hp: i32,
    level: i32,
    xp: i32,
    xp_needed: i32,
    gold: i32
}

impl Character {
    pub fn new(name: String) -> Character {
        let mut rng = thread_rng();

        let hp: i32 = rng.gen_range(12, 75);
        let gold: i32 = rng.gen_range(10, 50);

        Character { name: name, hp: hp, level: 1, xp: 0, gold: gold, xp_needed: 100 }
    }

    pub fn get_name(&self) -> String {
        self.name
    }

    // ...
}

How exactly am I breaking the rules here?

At a high-level, this is against-the-grain for Rust. You cannot transfer ownership of something borrowed because you don't own it.

Um don't I? I have other functions like:

pub fn get_hp(&self) -> i32 {
    self.hp
}

And that works just fine.

   |
23 |         self.name
   |         ^^^^ cannot move out of borrowed content

error: aborting due to previous error

What's going on? What is the appropriate approach to return the character name? Why does the get_hp method work but not get_name?

like image 272
TheWebs Avatar asked Dec 14 '22 03:12

TheWebs


1 Answers

The difference between get_hp and get_name is that get_hp returns a i32. i32 is a Copy type. Copy types can be copied by simply copying bits and are never moved out. On the other hand String is not Copy, it manages some memory which must either be transferred (moved out) or Cloned.

For getters like this, it is more idiomatic to return references instead of cloning. And for Strings, it should specifically be &str.

pub fn get_name(&self) -> &str {
    &self.name
}
like image 56
mcarton Avatar answered Dec 19 '22 12:12

mcarton