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