Henri Sivonen wrote:
I'm trying to understand how to translate Java arrays into Rust.
Short answer: The correct translation (as for most Java things) will
depend somewhat on how the array is being used. However, you may find
that `DVec<T>` is the closest to a "one-sized fits all" solution. Also,
this array is somewhat in flux: we have some ideas for how to manage
things that haven't yet been realized in the libraries (to some extent,
this is because language support is still a bit immature).
Why is mutability different for owned and managed vectors?
In general, mutability is inherited through owned (~) pointers---this
applies to both owned vectors but also other ~T types. This is because
the ~ pointer owns the data it points at, and in general we allow you to
mutate things that you own. A managed (@) pointer does not imply
ownership; you can think of owning as 'permission to free', and, in that
sense, the garbage collector is the owner.
But to put it more practically, @ data may be aliased, so if we allowed
you to change one @ from immutable to mutable or vice versa, the types
would not be consistent, and that would be unsound.
This compiles, however:
fn main() {
let mut v: @[mut i32] = @[mut 0, 0];
v[0] = 42;
let s = i32::to_str(v[0], 10);
io::println(s);
return;
}
Currently you can declare the *elements* of an array mutable using the
syntax you gave above. We generally discourage this because it is not
particularly compatible with higher-order functions, since at the moment
it is not possible to write a function that is parametric over
mutability. I discussed this somewhat in a blog post, though I think
the solution I proposed doesn't quite work out:
http://smallcultfollowing.com/babysteps/blog/2012/05/28/moving-mutability-into-the-type/
From a personal perspective, I am not fully satisfied with our approach
to mutability but I think it's a reasonable compromise. I hope we can
find something better but I think with better library support we can get
pretty far with what we have, and it may not be worth fixing. That's
one of those "up in the air" issues.
How is one supposed to implement growable buffers?
There are a couple of answers here. The real question is whether you
want to define a buffer that needs to be growable for a short time but
later becomes immutable, or whether you want to have some kind of buffer
that you modify over time. I'm guessing you want the latter. In that
case, the current best answer is probably to use
`libcore::dvec::DVec<T>` (or `@DVec<T>` if you want it to be managed).
If you can limit the duration of the mutability, I prefer the `build()`
function or a mutable local variable with a ~[T] value. It's more
efficient and rules out errors statically.
DVec<T> is pretty straightforward to use. Something like:
let v = dvec::DVec();
v.push(1);
v.push(2);
for v.each |i| { ... }
What's the Rust equivalent of System.arrayCopy() for efficiently
copying a range of elements from a vector to another?
I don't know that we have such a function. We could write one that uses
the type_needs_drop() intrinsic to decide between memcpy() and an
element-by-element copy.
Can a vector of object references have any empty slots? Or do empty
slots need to have some kind of dummy objects in them to avoid null
pointers?
You can use DVec<Option<@T>> if you want the slots to be nullable.
Niko
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev