Sami Nopanen wrote:
Hi,
Some random questions based on playing around with Rust for a few weeks.
1. Do mutable variant types allocated in stack always occupy a fixed
space (the size of the largest possibly value) ?
Yes.
2. How to allocate a mutable managed vector dynamically?
I can create an owned vector with: let a = vec::from_elem(..);
I can create a managed vector with: let a = at_vec::from_elem(..);
You cannot. Because the elements of a managed vector are stored inline
without indirection, and managed vectors are inherently shared, they
cannot change length after they are created. Think of a managed vector
like a Java array, which has the same properties.
If you want a mutable vector, you must place an owned vector into a
managed box. At the moment, this is most conveniently done using the
`DVec` wrapper (this is what it exists for). That is, a type like
`@DVec<T>` is basically the equivalent of Java's `ArrayList<T>`.
In the future, we currently plan to build in better support for managed,
mutable data using a plan, so it is likely that `@DVec<T>` will be
removed in favor of something like `@mut ~[T]`.
3. Can you return stack allocated literal vectors (either using the
create directly in calling stack semantic or as a copied value type)?
I tried:
fn newInStack() -> [int] { [1, 2] }
But was hit with a compile error.
You can only return types with a fixed size, and you cannot return
pointers into your own stack frame. The return type you gave here
(`[int]`) is not in fact a valid Rust type. Arrays come in two
varieties: pointers, like `~[int]`, `@[int]`, or `&[int]`, and
fixed-length, like `[int * 2]`. That function might best be written
using a fixed-length vector (`[int * 2]`), presuming of course you know
how long the result will be. This would be legal because the caller
would know how much memory to allocate in order to store the array on
their stack, and then the callee will write directly into the caller's
stack frame.
4. Can you control where a result gets built from the calling side?
Making several copies of a simple
constructor function to be able to allocate things in different places
seems a bit silly.
fn newInStack() -> Foo { Foo(1,2) }
fn newOwned() -> ~Foo { ~Foo(1,2) }
fn newManaged() -> @Foo { @Foo(1,2) }
Yes, that would be silly, but you don't have to do it. Just make the one
version that returns by value:
fn newFoo() -> Foo { Foo(1, 2) }
and then in the caller's side you can write `@newFoo()` or `~newFoo()`
as desired. This doesn't work with vector returns, though. If you want
to write a function that results in a vector of unknown length it's
easiest to just return `~[int]`, though it is possible to use generic
builder types to return either `@[int]` or `~[int]` depending on what
the user wants.
I especially was wondering about this in the context of 'vec' and
'at_vec' and trying (and failing) to create
a mutable managed array; and left wondering if I'd need to create a
new module 'at_mut_vec'. (And somewhere in
the back of my head wondering, if all these modules would really be
needed or if this is an indication of a
problem with expressiveness of the language in such cases).
There is something of a balancing act here. In principle there are many,
many ways that one could write generic functions (generic over @ vs ~,
generic over mutability, etc) but we've tried to keep that limited in
order to best manage complexity. There are ways to write functions and
types that maximize reusability:
• Use borrowed pointers whenever possible so that you can accept inputs
from anywhere (stack, `@`, `~`).
• Return value types (like `Foo`) instead of a pointer type (like `@Foo).
• If you can't use `&`, `~` is somewhat more general than `@`, because a
`~` value can always be placed into a managed box.
• Use inherited mutability rather than declaring mutability at the field
level to allow for freezing.
We are still tuning some of these aspects—particularly mutability—and we
plan on removing some of the "choices" that are available today, at
least once we're certain what the best choices are.
Niko
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev