Sto tentando di utilizzare una funzione di callback su un oggetto tratto. Ho ridotto il mio problema al seguente codice (playpen):Utilizzo di callback su oggetti tratto
trait Caller {
fn call(&self, call: fn(&Caller)) where Self: Sized {
call(self)
}
}
struct Type;
impl Caller for Type {}
fn callme(_: &Caller) {}
fn main() {
let caller: Box<Caller> = Box::new(Type);
caller.call(callme); // does not work
//callme(&*caller); // works
}
che si traduce in
<anon>:14:12: 14:24 error: the trait `core::marker::Sized` is not implemented for the type `Caller` [E0277]
<anon>:14 caller.call(callme); // does not work
^~~~~~~~~~~~
Aggiunta di un Sized
destinata a Caller
risultati in:
<anon>:3:14: 3:18 error: cannot convert to a trait object because trait `Caller` is not object-safe [E0038]
davvero non lo so capire perché ho bisogno del limite Sized
sul tratto. Funnily funziona se uso direttamente il callback. Come faccio a far funzionare questo?
Edit: Grazie per la risposta che la società si avvicinò con una bella soluzione
trait Caller {
fn borrow(&self) -> &Caller;
fn call(&self, call: fn(&Caller)) {
call(self.borrow())
}
}
struct Type;
impl Caller for Type {
fn borrow(&self) -> &Caller { self }
}
fn callme(_: &Caller) {}
fn main() {
let caller: Box<Caller> = Box::new(Type);
caller.call(callme);
}
Una cosa non mi è ancora chiara dopo aver letto questo: c'è un modo per far funzionare il codice dell'OP? – Shepmaster
Err, sì, ho dimenticato di rispondere effettivamente alla domanda. :) – huon
Grazie, ma quello che non capisco è il motivo per cui non è possibile trasformare & Self to & Caller. Non dovrebbe essere solo una trasformazione dell'identità come & Self è già un & Caller? Edit: La risposta è probabilmente che & Self non è & Caller ma potrebbe essere qualcos'altro ma sembra che dovrebbe essere risolvibile in rustc. – Ferio