ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Rust闭包学习心得

2022-03-07 17:04:45  阅读:203  来源: 互联网

标签:闭包 变量 Trait 学习心得 let Rust fn impl


  • move && Fn / FnMut / FnOnce

move 影响的是闭包如何捕获环境中的变量 , 影响的是闭包初始化之后外部变量是否还能继续使用。

闭包体内如何使用变量决定了闭包实现的是哪种Trait,影响了闭包自身的类型。但是闭包体使用的变量的方式同时也影响了闭包初始化之后外部变量能否继续使用。

也就是说环境变量能否在闭包初始化之后继续使用实际上被两点所影响,闭包是否有move参数,以及闭包体内使用变量的方式。所以可能会出现这种情况:闭包体内对变量的使用是最轻微的不可变引用,并未拿走所有权,但是初始化闭包的时候加了move参数,这导致了闭包在初始化之后环境变量就会不可用。

如何使用变量决定了闭包实现的是哪种Trait是什么意思?

  • 闭包的方法通过不可变引用访问其捕获的变量的闭包实现了Fn
  • 闭包的方法通过可变引用访问其捕获变量的闭包实现了FnMut
  • 闭包的方法若只能被调用一次,即实现了FnOnce。(说明闭包消耗了捕获的变量)。

Rust会根据闭包体和是否有move来推导如何捕获环境中变量,闭包捕获环境中变量的模式优先级顺序为:不可变借用,可变借用,移动。

fn main() {
    // 下面这段代码的闭包体中它没有获得变量的所有权,没有转让变量的所有权,
    // 所以这个闭包的类型是Fn()->Box<String>
    // 在闭包捕获完s之后原来的变量仍然能够使用
    let s = String::from("gef");
    let t = || {
        let s = &s;
        let g = Box::new((*s).clone());
        g
    };
    println!("{}", s);

    // 这个闭包的闭包体和上面仅有一处不同,那就是加了move,这会强行拿走s的所有权,即影响了捕获方式。
    // ****即使**** 闭包体看起来是用最普通的不可变引用来操作的环境中的变量,也看起来不该拿走变量的所有权
    let s = String::from("gef");
    let t = move || {
    let s = &s;
    let g = Box::new((*s).clone());
    g
    };
    // 不加注释会编译失败,s所有权已经被拿走了
    // println!("{}",s);
    // 即使用了move,这个闭包的类型依然是Fn()->Box<String>
    let fuck:Box<dyn Fn()->Box<String>>=Box::new(t);

    let s=String::from("gef");
    let t=||s;

    // 这行代码无法编译,因为s的所有权被移动到闭包里面去了,但如果闭包体是 &s,则可以编译
    // println!("{}",s)
    // 无论用不用move,这个闭包的类型都是FnOnce()->String, 因为闭包实现哪种Trait只和如何使用捕获到的变量有关系
    // 但是闭包体的代码在一定程度上影响了变量如何捕获,Rust会通过推导来决定要不要把变量的所有权转移到闭包体内
    // 对于没有实现Copy Trait的类型来说,不加move的话,环境变量会不会被拿走所有权,取决于闭包体内的使用方式
    // **但是如果加了move,无论闭包体怎么写,被捕获的环境变量(未实现Copy Trait)一定会被拿走所有权**
}

闭包的初始化行为只会执行一次,就是在闭包定义处,而不是在闭包执行处。在这个过程中会进行变量的捕获,且仅在闭包的定义处捕获一次,后期执行处不再进行捕获操作。

fn main(){
    let s=String::from("111");
    let g=||s;
    g();
    let g=||s; // 

标签:闭包,变量,Trait,学习心得,let,Rust,fn,impl
来源: https://www.cnblogs.com/hardsinging/p/15976655.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有