On 13/11/13 23:55, spir wrote:
Hello,

I have an error "cannot assign to immutable field". However, it is mutable as I understand according to "inherited mutability" rule exposed in the tutorial (section 'Structs'). The field in question is in a struct itself item of an array, itself field in a super-structure (lol!) which is self. All this happens in a method called on "&mut self". (And the compiler lets me change self elsewhere in the same method.) Thus, what is wrong? Or is it so that the mutability cascade is broken due to the array? How then restore it and be able to change a struct item's field? I guess arrays are mutable by default aren't they? (Or else, here it should due to inherited mutability, since it is a field of a mutable struct.)
What do I miss?

You need to use the .mut_iter() method, [T].iter() yields &T references, while the former yields &mut T references (and can only be used on vectors that have mutable contents, like ~[T] in a mutable slot, or &mut [T] or @mut [T]).

http://static.rust-lang.org/doc/master/std/vec/trait.MutableVector.html#tymethod.mut_iter

(Unfortunately the docs are not good with respect to built-in types. Methods can only be implemented on built-ins via traits, and the indication that the built-ins implement a trait is only shown on the page for the trait itself.)

[Code below untested yet due to error.]

    fn expand (&mut self) {
        // A mod table expands by doubling its list bucket capacity.
        // Double array of lists, initially filled with NO_CELL values.
        let NO_CELL : uint = -1 as uint;    // flag for end-of-list
        self.n_lists *= 2;
        self.lists = vec::from_elem(self.n_lists, NO_CELL);

        // replace cells into correct lists according to new key modulo.
        let mut i_list : uint;
        let mut i_cell : uint = 0;
        for cell in self.cells.iter() {
            // Link cell at start of correct list.
            i_list = cell.key % self.n_lists;
            cell.i_next = self.lists[i_list];           // ERROR ***
            self.lists[i_list] = i_cell;
            i_cell += 1;
        }
    }

I take the opportunity to ask whether there's an (i, item) iterator for arrays.

You can use the .enumerate() method on iterators, so

    for (i, cell) in self.mut_iter().enumerate() {
        ...
    }

http://static.rust-lang.org/doc/master/std/iter/trait.Iterator.html#method.enumerate


(Also, you will possibly meet with mutable borrow complaints (I'm not 100% sure of this), which you can address by destructuring self, so that the compiler knows all the borrows are disjoint:

let StructName { lists: ref mut lists, cells: ref mut cells, n_lists: ref mut n_lists } = *self;

and then use `lists`, `cells` and `n_lists` (they are just &mut references pointing to the corresponding fields of self).)

Huon

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to