Sono nuovo di ruggine e ho ancora qualche problema con la proprietà/il prestito. In questo caso, voglio memorizzare un FnOnce in un enum e poi chiamarlo in seguito da un altro thread. Ho provato molte varianti diverse ma sono sempre rimasto bloccato da qualche parte. Ecco una ridotta variante di quello che ho attualmente:FnOnce all'interno di Enum: non può uscire dal contenuto preso in prestito
#![feature(fnbox)]
use std::sync::{Arc, Mutex};
use std::boxed::{Box, FnBox};
enum Foo<T> {
DoNothing,
CallFunction(Box<FnBox(&T) + Send>)
}
struct FooInMutex<T> {
foo: Arc<Mutex<Foo<T>>>
}
impl<T> FooInMutex<T> {
fn put_fn(&self, f: Box<FnBox(&T)+Send>) {
let mut foo = self.foo.lock().unwrap();
let mut new_foo : Foo<T>;
match *foo {
Foo::DoNothing =>
new_foo = Foo::CallFunction(f),
_ =>
new_foo = Foo::DoNothing
}
*foo = new_foo;
}
fn do_it(&self, t: T) {
let mut foo = self.foo.lock().unwrap();
let mut new_foo : Foo<T>;
match *foo {
Foo::CallFunction(ref mut f) => {
//f(&t)
f.call_box((&t,));
new_foo = Foo::DoNothing;
}
_ =>
panic!("...")
}
*foo = new_foo;
}
}
#[test]
fn it_works() {
let x = FooInMutex { foo: Arch::new(Mutex::new(Foo::DoNothing)) };
x.put_fn(Box::new(|| panic!("foo")));
x.do_it();
}
io uso "rustc 1.4.0-serale (e35fd7481 2015/08/17)". Il messaggio di errore:
src/lib.rs:35:17: 35:18 error: cannot move out of borrowed content
src/lib.rs:35 f.call_box((&t,));
^
Da quanto ho capito, f è di proprietà della enum nella mutex e ho solo prendere in prestito tramite * foo. Ma per chiamare f, ho bisogno di spostarlo. Ma come farlo? O cos'altro devo cambiare per far funzionare questo esempio?
di riferimento Documentazione: [std :: :: mem sostituire] (http://doc.rust-lang.org/std/mem/ fn.replace.html) –
Puoi spiegare di più perché non ha funzionato in primo luogo? Perché 'f' deve essere spostato? – tafia
@tafia: 'FnBox' è basato su' FnOnce', che consuma l'ambiente di chiusura; cioè, 'f.call_box' prende' self' per valore, quindi 'f' deve essere' Box '. Un riferimento mutabile a quello non sarà sufficiente, e un riferimento mutabile è tutto ciò che avevi nel tuo esempio iniziale (quindi "non può uscire dal contesto preso in prestito", sta cercando di spostare il 'Box ' di un riferimento mutevole). –