0

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[..]

3
  • 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? Commented Apr 8, 2014 at 12:45
  • 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 :) Commented Apr 8, 2014 at 19:44
  • 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. Commented Apr 8, 2014 at 22:07

2 Answers 2

3

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).

Sign up to request clarification or add additional context in comments.

4 Comments

Note that &mut ~[...] is a mutable borrow, just one layer higher.
Thanks! So with your first example, using a "borrowed" pointer. This gives ownership of the pointer to the partition function for the scope of the function? And am I now using garbage collection? Or that's only for managed pointers?
Definitely no garbage collection. (GC only kicks in when you use the Rc or Gc types, now that the @ syntax has been mostly removed.)
The partition function does not get ownership in either of my examples. It's getting a borrowed mutable pointer. Notably though, only one mutable borrowed pointer to a particular value may exist at any point in time, so this makes it very similar to ownership semantics. (This is in contrast to immutable borrowed pointers, which are the default. You can lend out as many immutable borrowed pointers to values as you want.)
3

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.