• 捕获
    • 参见:

    捕获

    闭包本身是相当灵活的,可以实现所需功能来让闭包运行而不用类型标注(原文:Closures are inherently flexible and will do what the functionality requires
    to make the closure work without annotation)。这允许变量捕获灵活地适应使用
    情况,有时是移动(moving)有时是借用(borrowing)(原文:This allows capturing to
    flexibly adapt to the use case, sometimes moving and sometimes borrowing.)。闭包可以捕获变量:

    • 通过引用:&T
    • 通过可变引用:&mut T
    • 通过值:T

    它们更倾向于通过引用来捕获变量并且只在需要时才用后面用法(原文:They preferentially capture variables by reference and only go lower when
    required.)。

    1. fn main() {
    2. use std::mem;
    3. let color = "green";
    4. // 闭包打印 `color`,它会马上借用(`&`)`color` 并将该借用和闭包存储
    5. // 到 `print` 变量中。它会一保持借用状态直到 `print` 离开作用域。
    6. // `println!` 只需要`通过引用`,所以它没有采用更多任何限制性的内容。
    7. // (原文:`println!` only requires `by reference` so it doesn't
    8. // impose anything more restrictive.)
    9. let print = || println!("`color`: {}", color);
    10. // 使用借用来调用闭包。
    11. print();
    12. print();
    13. let mut count = 0;
    14. // 闭包使 `count` 值增加,可以使用 `&mut count` 或者 `count`,
    15. // 但 `&mut count` 限制更少,所以采用它。立刻借用 `count`。
    16. // (原文: A closure to increment `count` could take either
    17. // `&mut count` or `count` but `&mut count` is less restrictive so
    18. // it takes that. Immediately borrows `count`.)
    19. //
    20. // `inc` 前面需要加上 `mut`,因为 `&mut` 会必存储的内部。
    21. // 因此,调用该闭包转变成需要一个 `mut` 的闭包。
    22. // (原文:A `mut` is required on `inc` because a `&mut` is stored
    23. // inside. Thus, calling the closure mutates the closure which requires
    24. // a `mut`.)
    25. let mut inc = || {
    26. count += 1;
    27. println!("`count`: {}", count);
    28. };
    29. // 调用闭包。
    30. inc();
    31. inc();
    32. //let reborrow = &mut count;
    33. // ^ 试一试: 将此行注释去掉。
    34. // 不可复制类型(non-copy type)。
    35. let movable = Box::new(3);
    36. // `mem::drop` requires `T` so this must take by value. A copy type
    37. // would copy into the closure leaving the original untouched.
    38. //
    39. // `mem::drop` 要求 `T`,所以这必须通过值来实现(原文:`mem::drop`
    40. // requires `T` so this must take by value.)。可复制类型将会复制
    41. // 值到闭包而不会用到原始值。不可复制类型必须移动(move),从而
    42. // `可移动`(movable) 立即移动到闭包中(原文:A non-copy must
    43. // move and so `movable` immediately moves into the closure)。
    44. let consume = || {
    45. println!("`movable`: {:?}", movable);
    46. mem::drop(movable);
    47. };
    48. // `consume` 消费(consume)了该变量,所以这只能调用一次。
    49. consume();
    50. //consume();
    51. // ^ 试一试:将此行注释去掉。
    52. }

    参见:

    Boxstd::mem::drop