Today I think the only way you could do this is like so:
fn extendH(v:&mut HasList) {
let w = util::replace(&mut v.l, ~MT);
v.l = ~Cons(3, w);
}
Or, written using the swap operator:
fn extendH(v:&mut HasList) {
let mut w = ~MT;
v.l<-> w;
v.l = ~Cons(3, w);
}
This unfortunately requires a temporary allocation of ~MT to "plug into" v.l in the
interim before you have updated its value. You could avoid this by using an Option type, which at
least wouldn't require allocation. However, I think we could also add a helper like
`util::replace()` that updates the value "in-place", as you originally wanted. I imagine
something like this:
fn update<T>(v: &mut T, f: &fn(T) -> T) { unsafe { ... } }
and then you would write:
fn extendH(v:&mut HasList) {
util::update(&mut v.l, |l| ~Cons(3, l));
}
Niko
John Clements wrote:
I'm trying to figure out a clean way to juggle ownership to rearrange the parts
of a mutable structure. Specifically, in the example below, I want to take a
field containing an owned pointer and mutate it to point to a different
structure that contains the original value. After the move, the pointer is
again owned by the same structure, but the borrow checker is unhappy with me.
I've tried a bunch of variations using intermediate variables and 'match'ing,
but none of them have worked. Actually, it seems like I need an atomic
operation like the one described by Tucker Taft, where I move and
simultaneously set-to-null….
Is there some way to make this happen?[*]
// a list that uses owned pointers
pub enum IntList {
MT,
Cons(int,~IntList)
}
// a structure containing a list
pub struct HasList {
a : ~str,
l : ~IntList
}
// add a '3' at the head of the contained list
fn extendH(v:&mut HasList) {
v.l = ~Cons(3,v.l);
}
#[test] fn t1() {
let h = ~mut HasList {a:~"bogus",l:~MT};
extendH(h);
}
==>
rustc --test foo.rs
Running /usr/local/bin/rustc:
foo.rs:13:4: 13:5 error: use of partially moved value: `v`
foo.rs:13 v.l = ~Cons(3,v.l);
^
foo.rs:13:18: 13:21 note: field of `v` moved here because the field has type
~IntList, which is moved by default (use `copy` to override)
foo.rs:13 v.l = ~Cons(3,v.l);
^~~
foo.rs:13:4: 13:5 error: use of partially moved value: `v`
foo.rs:13 v.l = ~Cons(3,v.l);
^
foo.rs:13:18: 13:21 note: field of `v` moved here because the field has type
~IntList, which is moved by default (use `copy` to override)
foo.rs:13 v.l = ~Cons(3,v.l);
^~~
error: aborting due to 2 previous errors
John
[*] Naturally, I could just use a vector rather than the cons-pair
representation; I'm not looking for that answer.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev