Closures
Typinferenz in Rust
Abschnitt betitelt „Typinferenz in Rust“Welche der folgenden Aussagen beschreibt am besten die Begründung, warum Rust die Typen von Argumenten/Rückgabewerten für Closures, aber nicht für Top-Level-Funktionen inferiert?
Rust könnte theoretisch Typinferenz für Top-Level-Funktionen bereitstellen. Funktionale Sprachen wie Haskell und OCaml verfügen über diese Funktion. Die Rust-Designer haben jedoch bewusst entschieden, Typannotationen für Top-Level-Funktionen zu verlangen, um die Klarheit auf der Schnittstellenebene zu fördern: Eine Funktion wird immer genau den Typ haben, den sie angibt.
Closures und Ownership
Abschnitt betitelt „Closures und Ownership“Rust erlaubt Pattern Matching innerhalb von Closure-Argumenten, einschließlich der Verwendung des Unterstrichs. Zum Beispiel könnten Sie Folgendes schreiben:
let f = |_| (); // manchmal als "Toilet Closure" bezeichnetlet s = String::from("Hello");f(s);Welche der folgenden Aussagen beschreibt am besten die Beziehung zwischen f und s in diesem Programm?
Die „Toilet Closure“ ähnelt std::mem::drop, d.h. einer Funktion, die ein Argument verschiebt und bewirkt, dass es fallen gelassen wird (dropped).
Closures und mutable Borrows
Abschnitt betitelt „Closures und mutable Borrows“fn main() { let mut s = String::from("Hello"); let mut add_suffix = || s.push_str(" world"); println!("{s}"); add_suffix();}add_suffix leiht s zwischen seiner Definition und Verwendung mutabel aus, daher ist der println-Aufruf (ein Lesezugriff auf s) ungültig.
Closures mit Referenz-Parametern
Abschnitt betitelt „Closures mit Referenz-Parametern“fn main() { let mut s = String::from("Hello"); let add_suffix = |s: &mut String| s.push_str(" world"); println!("{s}"); add_suffix(&mut s);}Da add_suffix s nicht erfasst, ist es in Ordnung, s zu lesen, bevor es mit add_suffix mutiert wird.
Funktionstraits für Closures
Abschnitt betitelt „Funktionstraits für Closures“Betrachten Sie die folgende API:
/// Executes a function with a mutable reference to each element of a vectorfn for_each_mut<T, F: ___(&mut T)>(v: &mut Vec<T>, mut f: F) { for x in v.iter_mut() { f(x); }}Welcher der folgenden Funktionstraits ist am besten geeignet, um die Lücke zu füllen?
f wird mehrfach aufgerufen, daher ist FnOnce nicht geeignet. Sowohl Fn als auch FnMut können funktionieren, und FnMut ist weniger restriktiv, daher ist FnMut am besten geeignet.
Funktionstraits in Structs
Abschnitt betitelt „Funktionstraits in Structs“Betrachten Sie die folgende API:
pub struct Analyzer<F> { postprocess: F}
impl<F: ___(i32) -> i32> Analyzer<F> { fn process(&self, n: i32) -> i32 { /* .. */ } pub fn pipeline(&self, n: i32) -> i32 { let n = self.process(n); (self.postprocess)(n) }}Welcher der folgenden Funktionstraits ist am besten geeignet, um die Lücke zu füllen?
pipeline könnte mehrfach aufgerufen werden, daher ist FnOnce nicht geeignet.
pipeline nimmt eine unveränderliche Referenz auf self. Wäre postprocess vom Typ FnMut, könnte es nicht innerhalb von pipeline aufgerufen werden.
Daher ist Fn hier am besten geeignet.