写点什么

Rust:关于闭包的一点研究

用户头像
Microwood
关注
发布于: 2021 年 04 月 12 日
Rust:关于闭包的一点研究

闭包有三种类型,Fn、FnMut、FnOnce,其中 Fn 继承了 FnMut,FnMut 继承了 FnOnce,Fn 类型以不可变引用的形式捕获变量,不会修改环境变量且可以多次执行;FnMut 以可变引用的形式捕获变量,可以修改外部变量且可多次执行;FnOnce 捕获变量本身,只可以执行一次。

闭包还有一个关键字 move,可以将变量移动到闭包中,如果变量实现了 Copy trait,则执行 copy,否则不执行。下面举例来说明各种情况

1、如果闭包未捕获任何外部变量,则自动实现 Fn,闭包 c 可以多次执行

fn c1() {    let s = "hello";    let c = || {println!("hello rust")};    c();    c();}
复制代码

2、如果闭包捕获了 Copy 语义的不可变变量,则不管是否使用 move 关键字,都自动实现 Fn,闭包 c 可以多次执行

fn c2() {    let n = 1;    let c = move || {        println!("{}", n);    };    c();    c();    println!("{}", n);}
复制代码

3、如果闭包捕获了 Copy 语义的可修改变量并在闭包内部进行了修改,且没有使用 move 关键字,则闭包实现了 FnMut,可以多次调用,闭包内外操作的是同一个变量

fn c3() {    let mut n = 1;    let mut c = || {        n += 1;        println!("{}", n);    };    c();    c();    println!("{}", n);} //输出结果 2 3 3
复制代码

4、如果闭包捕获了 Copy 语义的可修改变量并在闭包内部进行了修改,且使用 move 关键字,则闭包实现了 FnMut,可以多次调用,闭包内的变量是外部变量的一个拷贝,对闭包的操作,不影响外部变量

fn c4() {    let mut n = 1;    let mut c =  move || {        n += 1;        println!("{}", n);    };    c();    c();    println!("{}", n);} //输出结果 2 3 1
复制代码

5、如果闭包捕获了移动语义的变量,则自动实现 FnOnce

fn c5() {    let s = "hello".to_string();    let c = || s;    c();    c(); //第二次调用会报错}
复制代码

6、如果闭包捕获了移动语义的变量,且在闭包内以引用(&)的形式使用,则闭包实现了 Fn,可以多次调用


fn c6() { let s = "hello".to_string(); let c = || {println!("{}", s)}; c(); c(); println!("{}", s);} //可以正常执行输出结果
复制代码

7、如果闭包捕获了移动语义的可变变量,且闭包内部进行了可变操作,且没有使用 move 关键字,则实现了 FnMut,可以多次执行,且闭包内外操作的是同一个变量

fn c7() {    let mut s = "rust".to_string();    let mut c = || {        s += " rust";        println!("{}", s);    };    c();    c();    println!("{}", s);}
复制代码

8、如果闭包捕获了移动语义的可变变量,且闭包内部进行了可变操作,且使用 move 关键字,则实现了 FnMut,可以多次执行,如果再次操作外部变量,会报错

fn c8() {    let mut s = "rust".to_string();    let mut c = move || {        s += " rust";        println!("{}", s);    };    c();    c();    println!("{}", s); //这里会报错}
复制代码

以上是对闭包的一点小总结,欢迎大家交流讨论。

发布于: 2021 年 04 月 12 日阅读数: 14
用户头像

Microwood

关注

一个只想开开心心写代码的程序员 2020.07.27 加入

一个主业是java,但是却更想把rust、python和js学得更好的程序员

评论

发布
暂无评论
Rust:关于闭包的一点研究