Il seguente codice viene compilato senza preavviso su ogni notte 1.7.0:Lieve tweak per il codice personalizzato FnBox impedisce di compilazione
trait FnBox {
fn call_box(self: Box<Self>);
}
impl <F: FnOnce()> FnBox for F {
fn call_box(self: Box<F>) {
(*self)()
}
}
fn main() {}
Ma quando faccio questa piccola modifica, che ho pensato che dire la stessa identica cosa, io ottenere un errore su FnOnce
non bloccato e non spostabile.
trait FnBox {
fn call_box(self: Box<Self>);
}
impl FnBox for FnOnce() {
fn call_box(self: Box<FnOnce()>) {
(*self)();
}
}
fn main() {}
Messaggio di errore:
practice.rs:7:10: 7:15 error: cannot move a value of type core::ops::FnOnce() + 'static: the size of core::ops::FnOnce() + 'static cannot be statically determined [E0161]
practice.rs:7 (*self)();
^~~~~
practice.rs:7:10: 7:15 help: run `rustc --explain E0161` to see a detailed explanation
error: aborting due to previous error
Qual è la differenza tra questi due esempi, e perciò non ci sono problemi con il primo?
buona risposta. Per ulteriori letture faremo anche riferimento al capitolo del Libro su [oggetti tratti] (https://doc.rust-lang.org/book/trait-objects.html) e alla [discussione su FnBox] (https://github.com/rust-lang/rust/issues/28796) –
'FnOnce' è sicuro per gli oggetti, è solo che il suo metodo non può essere chiamato attraverso un oggetto. * sicurezza oggetto * è equivalente a * tratto ha un tipo di oggetto *. Senza 'FnOnce',' FnMut' non potrebbe essere anche sicuro per gli oggetti. – bluss
@bluss, secondo la pagina della documentazione un tratto è sicuro per gli oggetti se non richiede 'Self: Sized' (' FnOnce' no) e se tutti i suoi metodi sono object-safe. Un metodo è object-safe se richiede o 'Self: Sized' (' call_once() 'no) o se non è nemmeno generico (' call_once() 'non è generico, quindi va bene) né usa' Self'. Quest'ultimo è il problema, perché 'call_once()' usa 'Self' sia implicitamente, come un tipo di' self', che esplicitamente, in 'Self :: Output', quindi' call_once() 'non è object-safe. Pertanto, 'FnOnce' non è sicuro anche per gli oggetti. –