Zum Inhalt springen

Closures

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.


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.


Betrachten Sie die folgende API:

/// Executes a function with a mutable reference to each element of a vector
fn 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.


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.