Post

🧀 understand mutability in Rust

mut in Rust

let v = 1

We know that if we want to change the value v later, we have to declare v as mutable

1
2
let mut v = 1;
v = 2;

Some articles says that mut v means v can point to other, which is way too wrong

Because such statement refer that v is a pointer.

variable name is address

This is my opinion.

The compiler will translate the name, which allow us write code conveinently , into address.

v=2 just tell the computer to change to value in the memory which address is associated with the name v due to the job of compiler.

struct data update

The instance of a struct is just group of spaces with value in the memory.

If we want to change the value like d.a=2 , basiclly we are changing the the value in that cellar of memory.

And if we want the right to change, we have to announce the right in the very first place.

iter

1
2
3
let v1 = vec![1,2,3];
let mut v1_iter = v1.iter();
let k = v1_iter.next();

why need mut here?

pub fn iter(&self) -> Iter<'_, T>

Because iter return the struct Iter

1
2
3
4
5
6
7
8
9
10
11
12
pub struct Iter<'a, T: 'a> {
    /// The pointer to the next element to return, or the past-the-end location
    /// if the iterator is empty.
    ///
    /// This address will be used for all ZST elements, never changed.
    ptr: NonNull<T>,
    /// For non-ZSTs, the non-null pointer to the past-the-end element.
    ///
    /// For ZSTs, this is `ptr::invalid(len)`.
    end_or_len: *const T,
    _marker: PhantomData<&'a T>,
}

All the method, like next() , called on v1_iter is just changing the internal state that the iterator uses to keep track of where it is in the sequence.

And that’s why next() method need to take the self argument as mutable.

1
2
3
4
5
6
7
8
fn main(){
    let v1 = vec![1,2,3];
    let v1_iter = v1.iter();

    for val in v1_iter{
        println!("{}",val);
    }
}

In this case, we don’t have to declare v1_iter as mutable, why?

The type of v1_iter is Iter, that it is Immutable slice iterator , which also is an iterator.

And for ... in xxx will call xxx’s into_iter method automatically.

Box

1
2
3
4
5
6
7
8
9
10
11
12
13
#[derive(Debug)]
struct Data{
    a : i32,
    b : String,
}


fn main(){
    let d = Box::new(Data{a:3,b:"hello".to_string()});
    println!("{:?}",*d);
    (*d).a = 1;
    println!("{:?}",*d);
}

d also have to declared as mutable, why? We are not going to change d, right?

If Rust allow this behavior, it will cause the violation against principle that only the owner or mutable borrower can change the value, e.g. let m = &d; (**m).a=2;

This post is licensed under CC BY 4.0 by the author.