move关键字是强制让环境变量的所有权转移到闭包中而不管是不是发生了所有权的转移

move关键字和匿名函数是否是FnOnce没有必然联系,之和匿名函数体有关

当匿名函数体里转移了环境变量的所有权的时候,匿名函数就是FnOnce。

当匿名函数体里改变了环境变量的值的时候,匿名函数就是FnMut。

否则匿名函数就是Fn。

关于move修饰的匿名函数需要注意的2点

1.如果函数不是FnOnce,此匿名函数可以重复调用

    let mut x = vec![1];
let mut incr_x = move || {
println!("{:?}", x);
x.push(1);
};
incr_x();
incr_x();
incr_x();

2.如果捕获变量是复制语义类型,则闭包会实现Copy/Clone。如果捕获变量是移动语义类型,则闭包不会实现Copy/Clone。普通闭包都是移动语义

fn call<F: FnOnce()>(f: F) { f() }

fn main() {
//未使用 move
let mut x = 0;
let incr_x = || x += 1;
call(incr_x);
// call(incr_x); // ERROR: 'incr_x' moved in the call above.
//使用 move
let mut x = 0;
let incr_x = move || x += 1;
call(incr_x);
call(incr_x);
//对移动语义类型使用move
let mut x = vec![];
let expend_x = move || x.push(42);
call(expend_x);
// call(expend_x); //ERROR: use of moved value: 'expend_x'
}

闭包类型(Fn,FnMut,FnOnce)和move关键字的更多相关文章

  1. c++ 右值引用,move关键字

    c++ move关键字 move的由来:在 c++11 以前存在一个有趣的现象:T&  指向 lvalue (左传引用), const T& 既可以指向 lvalue 也可以指向 rv ...

  2. tail -fn 1000 test.log | grep '关键字' 按照时间段 sed -n '/2014-12-17 16:17:20/,/2014-12-17 16:17:36/p' test.log /var/log/wtmp 该日志文件永久记录每个用户登录、注销及系统的启动、停机的事件

    Linux 6种日志查看方法,不会看日志会被鄙视的 2020-02-11阅读 7.3K0   作为一名后端程序员,和Linux打交道的地方很多,不会看Linux日志,非常容易受到来自同事和面试官的嘲讽 ...

  3. 第2课 类型推导(2)_decltype关键字

    1. decltype关键字 (1)auto所修饰的变量必须被初始化,编译器才能通过初始化来确定auto所代表的类型,即必须先定义变量. (2)decltype可以在编译期推导出一个变量或表达式的结果 ...

  4. 第1课 类型推导(1)_auto关键字

    1.  auto关键字 (1)auto的作用是让编译器自动推断变量的类型,而不需要显式指定类型.这种隐式类型的推导发生在编译期. (2)auto并不能代表实际的类型声明,只是一个类型声明的“占位符” ...

  5. FnOnce,FnMut和Fn

    继承结构 FnOnce FnMut: FnOnce Fn: FnMut FnOnce就是说会转移闭包捕获变量的所有权,在闭包前加上move关键字可以限定此闭包为FnOnce move关键字是强制让环境 ...

  6. C++ Primer : 第十一章 : 关联容器之概述、有序关联容器关键字要求和pair类型

    标准库定义了两种主要的关联容器:map和set map中的元素时一些关键字-值(key-value)对,关键字起到索引的作用,值则表示与索引相关的数据.set中每个元素只包含一个关键字,可以完成高效的 ...

  7. Rust基础笔记:闭包

    语法 Closure看上去是这样的: let plus_one = |x: i32| x + 1; assert_eq!(2, plus_one(1)); 首先创建一个绑定plus_one,然后将它分 ...

  8. [易学易懂系列|rustlang语言|零基础|快速入门|(7)|函数Functions与闭包Closure]

    [易学易懂系列|rustlang语言|零基础|快速入门|(7)函数Functions与闭包Closure] 有意思的基础知识 函数Functions与闭包Closure 我们今天再来看看函数. 在Ru ...

  9. 【译】理解Rust中的闭包

    原文标题:Understanding Closures in Rust 原文链接:https://medium.com/swlh/understanding-closures-in-rust-21f2 ...

随机推荐

  1. Android添加布局和按键

    Android添加布局和按键 Android布局方式分为 1.LinearLayout (线性布局) 2.ConstraintLayout (约束布局) 3.FrameLayout (帧布局) 4.T ...

  2. Python-100-Days-master

    跟着python100学习一下 100以内的素数 # 输出100以内的所有素数 # 想法:从1到100遍历,假设得到了i=17,那么此时从1到9遍历,如果找到了一个数用17能除尽则跳出循环 # 如果找 ...

  3. 使用client-go实现自定义控制器

    使用client-go实现自定义控制器 介绍 我们已经知道,Service对集群之外暴露服务的主要方式有两种:NodePort和LoadBalancer,但是这两种方式,都有一定的缺点: NodePo ...

  4. 中国电子云数据库 Mesh 项目 DBPack 的实践

    作者:刘晓敏 2022 年 4 月,中国电子云开源了其云原生数据库 Mesh 项目 DBPack.该项目的诞生,旨在解决用户上云过程中面临的一些技术难点,诸如分布式事务.分库分表等.由于它数据库 Me ...

  5. C# 四舍五入中一处易错点

    ,你没看错,四舍五入的结果 和我们期待的不太一样 Why?? 进入源码看下,注释中解释的很清楚.. 默认情况下,Math.Round()方法返回的是最接近的整数,这个没问题,问题是当要转换的数据在 两 ...

  6. 将 Ubuntu 16.04 LTS 的 Unity 启动器移动到桌面底部命令

    将 Ubuntu 16.04 LTS 的 Unity 启动器移动到桌面底部命令: gsettings set com.canonical.Unity.Launcher launcher-positio ...

  7. LVS简单搭建(一)

    先说一个坑: 192.168.65.110为虚拟ip,在主节点设置(ifconfig  eth0:8 192.168.65.110/24),其他子节点要与主节点保持一致(ifconfig  lo:3  ...

  8. 实现领域驱动设计 - 使用ABP框架 - 创建实体

    用例演示 - 创建实体 本节将演示一些示例用例并讨论可选场景. 创建实体 从实体/聚合根类创建对象是实体生命周期的第一步.聚合/聚合根规则和最佳实践部分建议为Entity类创建一个主构造函数,以保证创 ...

  9. Python在函数中使用列表作为默认参数

    在学习中遇到的Python的一个坑,那就是使用列表作为默认参数. 我们知道,在Python中,列表(list)是可变对象,所以列表的内容可能会在函数内改变.另一个需要注意的是,使用列表作为函数的默认参 ...

  10. Nginx通过bat文件快速启动停止

    新建文本文件NginxRun.bat.(名字无所谓,后缀名得是bat) 将以下代码复制到bat文件中即可. @echo off ::进入D盘 d: ::进入nginx目录 这里是自己的nginx目录 ...