xetra11
xetra11

Reputation: 8885

How to make this field mutable?

I'm stuck here for some time now and cannot figure out how to make the field word mutable. Can somebody please point me out the issue here.

pub struct Person<'name>{
    name:&'name Name
}

pub struct Name{
     word: String
}

impl<'name> Person<'name>{
    pub fn new(name:&'name mut Name)-> Person<'name>{
        Person {
            name: name
        }
    }
}

fn main(){
    let mut name: Name = Name {
        word: String::from("Petre")
    };
    let mut person: Person = Person::new(&mut name);
    first(&mut person);

}

pub fn first(person:&mut Person){
    person.name.word = String::from("Wurst");
    second(person);
}

pub fn second(person:&mut Person){
    println!("{}",person.name.word)
}

Output

error: cannot assign to immutable field `person.name.word`
  --> main.rs:27:5
   |
27 |     person.name.word = String::from("Wurst");
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Upvotes: 1

Views: 174

Answers (3)

ljedrz
ljedrz

Reputation: 22273

I think you expected person.name to be mutable due to the way you implemented the new() method for Person, where the name argument is a mutable reference to a Name struct:

fn new(name: &'name mut Name)

But this only means the function argument needs to be one - it doesn't result in the fact that the target Person's field can be mutated. You can pass a mutable reference to a target expecting an immutable reference, but you can't do it the other way round; you would get a values differ in mutability error.

As the others correctly pointed out, the field needs to be explicitly marked as mutable in order to allow its mutability:

struct Person<'name>{
    name: &'name mut Name
}

Upvotes: 1

Simon Whitehead
Simon Whitehead

Reputation: 65087

By marking the field as a mutable reference:

pub struct Person<'name>{
    name:&'name mut Name
} //            ^^^ mutable

Playground

Upvotes: 2

Chris Emerson
Chris Emerson

Reputation: 14051

Looking at your Person struct:

pub struct Person<'name>{
    name:&'name Name
}

The name field is an immutable reference, so you can't write through it. Simply make it a mutable reference:

pub struct Person<'name>{
    name:&'name mut Name
}

(playground)

Upvotes: 7

Related Questions