0
votes

I'm just playing around with rust for the first time, implementing quicksort, and I'm stuck on references to dynamically sized arrays (I had no problem with fixed size arrays).

I would like to have an indefinitely sized array of integers to sort, which I gather I can create with something like:

let array = ~[1,2,3,4,3,2,1];

However, I am not sure how I can pass this by reference into a partition function.

partition ( a : &mut ~[uint], p: uint, i: uint) {
     // partition a, in place
}

As soon as I try to reorder any elements in a, the compiler complains:

error: cannot assign to immutable vec content a[..]

2
I think we'll need more code to be able to help, since &mut ~[...] says that the vector (and its data) that a points at is mutable. At a guess, you've written something like a = ... at some point? - huon
Yes, at the end of the partition algorithm, I'm trying to swap two elements in the array. This is when I get the error. Both answers below seem to be viable, though. I'm not sure which one is "more" correct and thus I should accept as the correct(est) answer :) - rdmcfee
To be honest, I don't quite understand why either of them would fix that error message, since they're just shuffling the types around, AFAICT, not making a fundamental change. - huon

2 Answers

3
votes

With 0.10 the language is undergoing some changes to array types at the moment, so things are a bit messy. Vec<T> is Rust's intended dynamically sized array type.

let vec = vec!(1u,2,3,4,3,2,1);

partition ( a : &mut Vec<uint>, p: uint, i: uint) {
     // partition a, in place
}

Note that indexing of a Vec via brackets is currently only possible by first calling .as_slice() or .as_mut_slice() on it since the respective traits are not yet implemented.

3
votes

You should use a mutable borrow of the vector rather than a mutable borrow of a pointer to a vector, so you should get rid of that ~ pointer in the type of your partition function. For example:

fn partition(_: &mut [uint], _: uint, _: uint) { }

fn main() {
    let mut array = ~[1, 2, 3, 4, 3, 2, 1];
    partition(array, 0, 0);
}

Notice that array is automatically passed as a mutable borrowed pointer.

If you use a Vec instead, then you need to explicitly create a slice:

fn partition(_: &mut [uint], _: uint, _: uint) { }

fn main() {
    let mut array = vec!(1, 2, 3, 4, 3, 2, 1);
    partition(array.as_mut_slice(), 0, 0);
}

Both code snippets should compile on the latest Rust (from tip).