[][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