[−][src]Function tao_of_rust::ch06::closures::closure_gen_type
pub fn closure_gen_type()
闭包生成类型
Base usage: Copy语义自动实现Fn
fn main() { let s = "hello"; let c = ||{ println!("{:?}", s) }; c(); c(); println!("{:?}", s); }Run
Base usage: 模拟闭包生成的结构体和trait
#![feature(unboxed_closures, fn_traits)] struct Closure<'a> { env_var: &'a u32 } impl<'a> FnOnce<()> for Closure<'a> { type Output = (); extern "rust-call" fn call_once(self, args: ()) -> () { println!("{:?}", self.env_var); } } impl<'a> FnMut<()> for Closure<'a> { extern "rust-call" fn call_mut(&mut self, args: ()) -> () { println!("{:?}", self.env_var); } } impl<'a> Fn<()> for Closure<'a> { extern "rust-call" fn call(&self, args: ()) -> () { println!("{:?}", self.env_var); } } fn main(){ let env_var = 42; let mut c = Closure{env_var: &env_var}; c(); //42 c.call_mut(()); // 42 c.call_once(()); // 42 }Run
Base usage: 实现Fn,必然要实现FnMut和FnOnce
#![feature(fn_traits)] fn main() { let s = "hello"; let mut c = ||{ println!("{:?}", s) }; c(); // "hello" c(); // "hello" c.call_mut(()); // "hello" c.call_once(()); // "hello" c(); // "hello" 这里没有被转移所有权是因为生成的FnOnce自动实现的Copy println!("{:?}", s); // "hello" }Run
Base usage: 转移语义类型自动实现FnOnce
fn main() { let s = "hello".to_string(); let c = || s; c(); // c(); // error: use of moved value: `c` // println!("{:?}", s); // error: use of moved value: `s` }Run
Base usage: 实现FnOnce,不需要实现Fn和FnMut
#![feature(fn_traits)] fn main() { let mut s = "hello".to_string(); let c = || s; c(); // error: expected a closure that implements the `FnMut` trait, // but this closure only implements `FnOnce` // c.call(()); // error: expected a closure that implements the `FnMut` trait, // but this closure only implements `FnOnce` // c.call_mut(()); // c(); // error: use of moved value: `c` // println!("{:?}", s); // error use of moved value: `s` }Run
Base usage: 使用move关键字
fn main() { let s = "hello"; let c = move ||{ println!("{:?}", s) }; c(); c(); println!("{:?}", s); }Run
Base usage: 使用move关键字会影响到闭包自身吗
fn call<F: FnOnce()>(f: F) { f() } // 未使用move fn main() { let mut x = 0; let incr_x = || x += 1; call(incr_x); // call(incr_x); // ERROR: `incr_x` moved in the call above. // 使用move let mut x = 0; let incr_x = move || x += 1; call(incr_x); call(incr_x); // 对移动语义类型使用move let mut x = vec![]; let expend_x = move || x.push(42); call(expend_x); // call(expend_x); // ERROR: use of moved value: `expend_x` }Run
Base usage: 修改环境变量自动实现FnMut
fn main() { let mut s = "rush".to_string(); { let mut c = ||{ s += " rust" }; c(); c(); // error: cannot borrow `s` as immutable // because it is also borrowed as mutable // println!("{:?}", s); } println!("{:?}", s); }Run
Base usage: 实现FnMut必然会实现FnOnce,但不会实现Fn
#![feature(fn_traits)] fn main () { let mut s = "rush".to_string(); { let mut c = || s += " rust"; c(); // error: expected a closure that implements the `Fn` trait, // but this closure only implements `FnMut` // c.call(()); c.call_once(()); // error: cannot borrow `s` as immutable // because it is also borrowed as mutable // println!("{:?}",s); } println!("{:?}",s); // "rush rust rust" }Run
Base usage: 未捕获任何环境变量自动实现Fn
fn main() { let c = ||{ println!("hhh") }; c(); c(); }Run