Home>

In Rust, I'd like to write code that has variable references as elements in an array and changes them all at once.
The following code has been compiled. (rustc 1.38.0)

fn main () {
    let mut a = 1;
    let mut b = 2;
    let c = [&mut a,&mut b];
    add1s (c);
    println! ("{}, {}", a, b);// =>2, 3
}
fn add1s (c: [&mut i32;2]) {
    * c [0] + = 1;
    * c [1] + = 1;
}

I want to replace the contents of thisadd1swithfor statementorfor_each () {...}for an iterator.

fn add1s (c: [&mut i32;2]) {
    // * c [0] + = 1;
    // * c [1] + = 1;
    for x in c.iter () {
        ** x + = 1;
    }
}
|
14 | for x in c.iter () {
   --help: consider changing this to be a mutable reference: `&mut&mut i32`
15 | ** x + = 1;
   | ^^^^^^^^ `x` is a`&`reference, so the data it refers to cannot be written


It will be said. Since* xbecomes a variable reference toa, b, I thought that the contents could be rewritten with the unreferenced** xHowever, the cause of the error is thatxitself is not a variable reference, it is just a reference, so the contents cannot be rewritten.
In short, does it mean that iterator elements cannot be extracted with a for statement?
If there is a workaround (a method that does not need to be written for each element like* c [0] = ...;* c [1] = ...;) I'm happy.

  • Answer # 1

    Useiter_mutinstead of

    iter.

    fn add1s (mut c: [&mut i32;2]) {
        // * c [0] + = 1;
        // * c [1] + = 1;
        for x in c.iter_mut () {
            ** x + = 1;
        }
    }
    When

    iteris used, it tries to iterate over the element&&mut i32, but Rust allows&&mut Tdereferencing This makes it impossible to write** x(if possible, a copy of&mut Tcan be easily created, and&mut TBreaks the constraint that there is only one). If it isiter_mut, it becomes&mut&mut i32and can be dereferenced.

    By the way, in Rust,foris subject to&seq rather thanseq.iter ()orseq.iter_mut ()and&mut seqare preferred, so the following is actually preferable.

    fn add1s (mut c: [&mut i32;2]) {
        // * c [0] + = 1;
        // * c [1] + = 1;
        for x in&mut c {
            ** x + = 1;
        }
    }

    Although it may be a little bit tiring, I don't often see how to write[&mut T]in Rust. Of course, I think there are cases where it is absolutely necessary, but in many cases, I often use&mut [T].
    If you just want to edit the elements of the array freely, we recommend the following.

    fn main () {
        let a = 1;
        let b = 2;
        let c =&mut [a, b];
        add1s (c);
        println! ("{}, {}", a, b);// =>2, 3
    }
    fn add1s (c:&mut [i32;2]) {
        // * c [0] + = 1;
        // * c [1] + = 1;
        for x in c {
            * x + = 1;
        }
    }