Calvin's Marbles


  • 首页

  • 关于

  • 归档

  • 标签

  • 搜索

引用下面的Demo。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#[derive(Debug)]
struct E {
a: String,
}

impl Drop for E {
fn drop(&mut self) {
println!("destroyed struct E");
}
}

fn fn_once<F>(func: F) where F: FnOnce() {
println!("fn_once begins");
func();
// func(); // @1
println!("fn_once ended");
}


fn test_fn_once() {
let e = E { a: "fn_once".to_string() };
// let f = move || println!("fn_once move calls: {:?}", e); // @2
let f = || println!("fn_once calls: {:?}", e);
fn_once(f);
println!("main ended");
}


fn fn_<F>(func: F) where F: Fn() {
println!("fn begins");
func();
func();
println!("fn ended");
}

fn test_fn(){
let e = E { a: "fn".to_string() };
let f = move || println!("fn move calls: {:?}", e);
// let f = || println!("fn calls: {:?}", e);
fn_(f);
println!("main ended");
}

fn fn_mut<F>(mut func: F) where F: FnMut() {
println!("fn begins");
func();
func();
println!("fn ended");
}

fn test_fn_mut(){
let e = E { a: "fn_mut".to_string() };
let f = move || println!("fn_mut move calls: {:?}", e);
// let f = || println!("fn_mut calls: {:?}", e);
fn_(f);
println!("main ended");
}
  1. FnOnce
    检查输出,可以发现在main函数退出后,e才销毁。

    1
    2
    3
    4
    5
    fn_once begins
    fn_once calls: E { a: "fn_once" }
    fn_once ended
    main ended
    destroyed struct E

    但如果使用@2处的代码,则输出如下。发现e被move到闭包里面去了,并且在闭包退出时就被销毁了。

    1
    2
    3
    4
    5
    fn_once begins
    fn_once move calls: E { a: "fn_once" }
    destroyed struct E
    fn_once ended
    main ended

    如果取消@1处的注释,那么编译报错。这也是符合闭包是FnOnce的认知的。

  2. Fn
    不使用move版本

    1
    2
    3
    4
    5
    fn begins
    fn calls: E { a: "fn" }
    fn ended
    main ended
    destroyed struct E

    使用move版本

    1
    2
    3
    4
    5
    fn begins
    fn move calls: E { a: "fn" }
    fn ended
    destroyed struct E
    main ended
  3. FnMut
    将上面的代码简单改成FnMut,发现无论是move还是非move版本都无法编译,给出cannot borrow as mutable错误。
    需要改成mut func: F才行。

Calvin Neo

Calvin Neo

243 日志
152 标签
RSS
GitHub Twitter Weibo
Links
  • xqq
  • wenwen
  • zyyyyy
© 2015 - 2025 Calvin Neo   Hosted by Coding Pages
版权声明
由 Hexo 强力驱动
主题 - NexT.Muse