On 11/08/2012 11:46 AM, Paul Harvey wrote:
Hi all,
This started here(https://github.com/mozilla/rust/issues/3928) and i
would like to continue with my questions.
So, where i left off was:
* How to share a *cloned channel* with mutliple tasks
* How to share a port from main into a task
* How to determine how copyable a channel/port is
* Is it possible to create dynamic topologies with port and channels
in Rust at runtime (although i think that this one is a no)
Here's the last example on that issue that you had problems with:
|let chan = SharedChan(move chan);
let a = chan.clone();
do task::spawn |move a| {
send_actor(a);
}|
This will cause a compiler error at `send_actor(a)` because a isn't
copyable. Pipe-based channels and ports are never copyable but
SharedChan's, like you have here, may be cloned with the .clone()
method. Pipes are linear types and are typically moved around with
`move` expressions, unless one really needs to create another reference.
With that in mind one might be tempted to `move` a into the `send_actor`
function, like `send_actor(move a)`. In this case that won't work
because `a` has been captured in a closure, and once variables are
captured they are stuck inside the closure (moving a variable out of a
closure would leave a 'hole' in the closure environment that make
calling the closure a second time unsound). In this case you have two
options. Since you have a cloneable SharedChan the easiest thing here is
to just clone 'a':
do task::spawn |move a| {
send_actor(a.clone())
}
Another common situation is to have just a `Chan` type, in which case
clone is not possible. Right now for such a scenario the common thing to
do to move that value around is to use a Cell type.
use std::cell::Cell;
let (port, chan) = pipes::stream();
let chan_cell = Cell(move chan);
do task::spawn |move chan_cell| {
send_actor(chan_cell.take());
}
The Cell is like a mutable Option type, you can put things in and take
things out. It lets one get around the previously mentioned limitation
about moving values out of closures. FWIW, Rust will also be getting
'once functions', which are closures that may be only called a single
time, and whose environments may be moved out. Spawn will eventually
take a once function to avoid this problem.
As to 'detecting' how copyable a value is, copyability is an intrinsic
property of the type. Copyable types intrinsically implement the `Copy`
trait, but there is no declaration on the type itself to indicate it's
copyability. Often you only know when the compiler tells you something
can't be copied.
Ports can be moved the same as channels.
I don't understand the dynamic topology issue but I think the answer is
that pipes can't do that: both the port and channel endpoints are linked
to each other at creation; they cannot be created independently and
linked later.
Regards,
Brian
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev