Rust作为输入参数

大家已经注意到,Rust选择无需注解在运行时捕捉变量。这在正常使用时很方便,但是编写函数时,这种模糊性是不允许的。封闭的类型齐全,包括其捕获类型必须注明。捕获封闭使用被注释为以下特征之一的方式:

  • Fn: 通过引用以捕获 (&T)
  • FnMut: 通过可变引用需要捕获 (&mut T)
  • FnOnce: 通过值捕获 (T)

即使是注释,这些都是非常灵活: FnOnce的一个参数指定封闭可以通过T或 &mut T 或 &T在将捕获(如果此举是可能的,任何类型的借还应该是可能的)。 反向并非如此:如果该参数为Fn,那么什么都降低是允许的。因此,规则是:

  • 任何注释的参数限制捕捉到自身

此外,Rust会优先捕捉,可变通过变量基础变量限制最少的方式:

// A function which takes a closure as an argument and calls
// it. The closure takes no input and returns nothing.
fn apply(f: F) where
    F: FnOnce() {
    // ^ TODO: Try changing this to `Fn` or `FnMut`.

    f()
}

// A function which takes a closure and returns an `i32`.
fn apply_to_3(f: F) -> i32 where
    // The closure takes an `i32` and returns an `i32`.
    F: Fn(i32) -> i32 {

    f(3)
}

fn main() {
    let greeting = "hello";
    // A non-copy type.
    let mut farewell = "goodbye".to_owned();

    // Capture 2 variables: `greeting` by reference and
    // `farewell` by value.
    let diary = || {
        // `greeting` is by reference: requires `Fn`.
        println!("I said {}.", greeting);

        // Mutation forces `farewell` to be captured by
        // mutable reference. Now requires `FnMut`.
        farewell.push_str("!!!");
        println!("Then I screamed {}.", farewell);
        println!("Now I can sleep. zzzzz");

        // Manually calling drop forces `farewell` to
        // be captured by value. Now requires `FnOnce`.
        drop(farewell);
    };

    // Call the function which applies the closure.
    apply(diary);

    let double = |x| 2 * x;

    println!("3 doubled: {}", apply_to_3(double));
}

联系我们

邮箱 626512443@qq.com
电话 18611320371(微信)
QQ群 235681453

Copyright © 2015-2022

备案号:京ICP备15003423号-3