继承结构

FnOnce

FnMut: FnOnce

Fn: FnMut

FnOnce就是说会转移闭包捕获变量的所有权,在闭包前加上move关键字可以限定此闭包为FnOnce

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

#![feature(core_intrinsics)]
fn print_type_of<T>(_: T) {
println!("{}", unsafe { std::intrinsics::type_name::<T>() });
} fn main() {
let i = vec![1];
let x: Box<dyn FnOnce() -> ()> = Box::new(move || {
// print_type_of(i);
println!("{:?}", i);
});
x();
println!("{:?}", i);
}

上面代码会报错

当然如果i是一个实现呢Copy的变量就不会报错了,因为Copy变量会自动复制而不会转移所有权

不用move关键字,只要闭包类转移了环境变量的所有权,闭包就只会实现FnOnce

#![feature(fn_traits)]
fn main() {
let mut i = vec![1];
let mut fn1 = || {
i
};
fn1.call_mut(());
  fn1.call(());
  fn1.call_once(());

}

上面代码报错,因为fn1只实现了call_once方法

FnMut就是改变了捕获变量

fn main() {
let mut i = vec![1]; let mut x: Box<dyn FnMut() -> ()> = Box::new(|| {
i.push(2);
}); x();
}

这个代码里dyn FnMut() -> ()可以改为dyn FnOnce() -> (),但是不能改为dyn Fn() -> ()。因为实例是一个FnMut,只能往上转型,不能往下转型

FnMut捕获是按可变借用捕获的,所以FnMut捕获的变量在闭包外也是不能使用的,即使被捕获的变量实现了Copy

    let mut i = 1;

    let mut x: Box<dyn FnMut() -> ()> = Box::new(|| {
i = i + 1;
}); x();
println!("{}", 1 + i);

上面代码的错误简化下就是

fn test(ii: &mut i32, i: i32) {}

fn main() {
let mut i = 1;
let ii = &mut i;
test(ii, i);
}

如果需要变量在FnMut后还能使用,需要用Mutex模拟。用Mutex模拟后,闭包也不再是FnMut了,而是Fn

use std::sync::Mutex;

fn main() {
let mut i = Mutex::new(1); let mut x: Box<dyn Fn() -> ()> = Box::new(|| {
let mut ii = i.lock().unwrap();
*ii = 2;
}); x();
let iii = i.lock().unwrap();
println!("{}", iii);
}

一个啥也不干的闭包就是Fn了,Fn以不可变借用捕获环境变量

fn main() {
let x: Box<dyn Fn() -> ()> = Box::new(|| {
});
}

Fn能调用FnMut和FnOnce的方法

#![feature(fn_traits)]
fn main() {
let mut fn1 = || {};
fn1.call_mut(());
fn1.call_once(());
}

FnOnce,FnMut和Fn的更多相关文章

  1. 【译】理解Rust中的Futures(二)

    原文标题:Understanding Futures in Rust -- Part 2 原文链接:https://www.viget.com/articles/understanding-futur ...

  2. 闭包类型(Fn,FnMut,FnOnce)和move关键字

    move关键字是强制让环境变量的所有权转移到闭包中而不管是不是发生了所有权的转移 move关键字和匿名函数是否是FnOnce没有必然联系,之和匿名函数体有关 当匿名函数体里转移了环境变量的所有权的时候 ...

  3. JavaScript中fn()和return fn()

    看博客时,注意到return的重要性 参考:http://www.cnblogs.com/raoyunxiao/p/5644032.html 看似反常的例子: var i = 0; function ...

  4. ubuntu系统(华硕笔记本)屏幕亮度用Fn控制的调节设置

    亲测配置: 系统:Linux lite 3.2 x86_64(Ubuntu其他版本可参考修改) 笔记本:华硕(asus)1201N 达到的效果: 可以正常使用Fn+F5调暗,Fn+F6调亮. 设置步骤 ...

  5. 设置Fn键 笔记本直接按F1-F12 无须按Fn键 Fn+F12改F12(联想小新300为例)

    最近公司给配的笔记本联想小新300 80RT  i7-6500U 4G内存 500G机械,后加装120G固态+4G内存 这样就感觉还不错了. 在使用这本子的时候,去了Win10,强行装了Win7.无线 ...

  6. jquery.fn.extend与jquery.extend--(初体验二)

    1.jquery.extend(object); 为扩展jQuery类本身.为类添加新的方法. jquery.fn.extend(object);给jQuery对象添加方法. $.extend({ a ...

  7. jQuery为开发插件提拱了两个方法:jQuery.fn.extend(); jQuery.extend();

    jQuery为开发插件提拱了两个方法,分别是: jQuery.fn.extend(); jQuery.extend(); jQuery.fn jQuery.fn = jQuery.prototype ...

  8. Jquery揭秘系列:实现$.fn.extend 和$.extend函数

    前面我们扩展了bind方法和ready函数,这次我要讲一下$.fn.extend 和$.extend函数. 其他的不多说,直接切入主题吧! 先来看看这两个函数的区别: $.fn.extend是为查询的 ...

  9. java Fn键

    需求分析 我想开机禁用触摸板. 方案设计 安装驱动:比较麻烦,驱动也不一定支持开机禁用触摸板. 编程实现,让一段代码开机禁用触摸板 编程实现也分好几种方法: 使用windows API禁用触摸板,这需 ...

随机推荐

  1. Django学习——图书管理系统图书修改、orm常用和非常用字段(了解)、 orm字段参数(了解)、字段关系(了解)、手动创建第三张表、Meta元信息、原生SQL、Django与ajax(入门)

    1 图书管理系统图书修改 1.1 views 修改图书获取id的两种方案 1 <input type="hidden" name="id" value=& ...

  2. Node.js躬行记(19)——KOA源码分析(上)

    本次分析的KOA版本是2.13.1,它非常轻量,诸如路由.模板等功能默认都不提供,需要自己引入相关的中间件. 源码的目录结构比较简单,主要分为3部分,__tests__,lib和docs,从名称中就可 ...

  3. Golang:手撸一个支持六种级别的日志库

    Golang标准日志库提供的日志输出方法有Print.Fatal.Panic等,没有常见的Debug.Info.Error等日志级别,用起来不太顺手.这篇文章就来手撸一个自己的日志库,可以记录不同级别 ...

  4. 【工具-Nginx】从入门安装到高可用集群搭建

    文章已收录至https://lichong.work,转载请注明原文链接. ps:欢迎关注公众号"Fun肆编程"或添加我的私人微信交流经验 一.Nginx安装配置及常用命令 1.环 ...

  5. 安装Zookeeper到Linux

    系统版本:Ubuntu 16.04.5 LTS 软件版本:apache-zookeeper-3.5.8 硬件要求:无 1.安装依赖 Zookeeper需要JDK的支持. 注:需要先去JDK官网下载安装 ...

  6. 主管发话:一周搞不定用友U8 ERP跨业务数据分析,明天就可以“毕业”了

    随着月末来临,又到了汇报总结的时刻. (图片来自网络) 到了这个特殊时期,你的老板就一定想要查看企业整体的运转情况.销售业绩.客户实况分析.客户活跃度.Top10 sales. 产品情况.订单处理情况 ...

  7. 解读ICDE'22论文:基于鲁棒和可解释自编码器的无监督时间序列离群点检测算法

    摘要:本文提出了两个用于无监督的具备可解释性和鲁棒性时间序列离群点检测的自动编码器框架. 本文分享自华为云社区<解读ICDE'22论文:基于鲁棒和可解释自编码器的无监督时间序列离群点检测算法&g ...

  8. MTK 虚拟 sensor bring up (pick up) sensor2.0

    pick up bring up sensor2.0 1.SCP侧的配置 (1) 放置驱动pickup.c (2) 添加底层驱动文件编译开关 (3) 加入编译文件 (4) 增加数据上报方式 (5)修改 ...

  9. 【SpringSecurity系列3】基于Spring Webflux集成SpringSecurity实现前后端分离无状态Rest API的权限控制

    源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/02-springsecurity-state ...

  10. RPA人力资源简历筛选机器人

    简历自动筛选及分析机器人,支持前程无忧.猎聘 1.自动登录招聘网站 2.自动填充简历筛选条件 3.RPA依次读取所筛选的简历信息 4.自动将简历数据复制到本地文档中 5.完成简历信息收集及分析表 6. ...