FnOnce , FnMut <RUST>
FnOnce
1 #[lang = "fn_once"]
2 #[must_use = "closures are lazy and do nothing unless called"]
3 pub trait FnOnce<Args> {
4 type Output;
5 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
6 }
The version of the call operator that takes a by-value receiver.
Instance of FnOnce can be called, but might not be callable multiple times. Because of this, if the only thing known about a type is that it implements FnOnce, it can only be called once.
FnOnce is implemented automatically by closure that might consumer captured variable, as well as all types that implement FnMut, e.g(safe)function pointer (since FnOnce is a supertrait of FnMut).
Since both Fn and FnMut are subtraits of FnOnce, any instance of Fn or FnMut can be used where a FnOnce is expected.
Use FnOnce as a bound when you want to accept a parameter of function-like type and only need to call it once. If you need to call the parameter repeatedly, use FnMut as a bound; if you also need it to not mutate state, use Fn.
Aslo of note is the sapcial syntax for Fn traits(e.g Fn(usize, bool) -> usize). Those interested in the technical details of this can refer to the relevant section in the Rustonmicon.
1 fn consume_with_relish<F>(func: F)
2 where F: FnOnce() -> String
3 {
4 // 'func' consumers it captured variables, so it cannot be run more than once.
5 println!("Consumed: {}", func());
6
7 println!("Delicious!");
8
9 //Attempting to invoke 'func()' again will therow a 'use of moved
10 // value 'error for 'func'
11 }
12
13 let x = String::from("x");
14 let consume_and_return_x = move || x;
15 consume_with_relish(consume_and_return_x);
FnMut
1 Trait std::ops::FnMut
2
3 #[lang = "fn_mut"]
4 #[must_use = "clousure are lazy and do nothing unless called"]
5 pub trait FnMut<Args>: FnOnce<Args> {
6 extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
7 }
The version of the call operator that takes a mutale receiver.
Instance of FnMut can be called repeatedly and many mutate state.
FnMut is implemented automatically by closures which take mutable reeferences to captured variables, as well as all types that implement Fn, e.g, (safe) functuin pointer(since FnMut is a supertrait of Fn). Additionally, for any type F that implements FnMut, &mut F implements FnMut, too.
1 pub fn map<F, T, U>(values: Vec<T>, mut f: F) -> Vec<U>
2 where F: FnMut(T) -> U, {
3 let mut v = Vec::with_capacity(values.len());
4 for val in vlaues {
5 v.push(f(val));
6 }
7 v
8 }
9
10
11 fn square(x: i32) -> i32 {
12 x * x
13 }
14
15 #[test]
16 fn func_single() {
17 let input = vec![2];
18 let expected = vec![4];
19 assert_eq!(map(input, square), expected);
20 }
21
22 #[test]
23 #[ignore]
24 fn func_multi() {
25 let input = vec![2, 3, 4, 5];
26 let expected = vec![4,9,16,25];
27 assert_eq!(map(input, square),expected);
28 }
29
30 #[test]
31 #[ignore]
32 fn closure() {
33 let input = vec![2, 3, 4, 5];
34 let expected = vec![4,9, 16, 25];
35 assert_eq!(map(input, |x| x*x), expected);
36 }
37
38 #[test]
39 #[ignore]
40 fn closure_floats() {
41 let input = vec![2.0, 3.0, 4.0, 5.0];
42 let expected = vec![4.0, 9.0, 16.0, 25.0];
43 assert_eq!(map(input, |x| x*x), expected);
44 }
45
46 #[test]
47 #[ignore]
48 fn strings() {
49 let input = vec!["1".to_stirng(), "2".into(), "3".into()];
50 let expected = vec!["11".to_string(), "22".into(), "33".into()];
51 assert_eq!(map(input, |s| s.repeat(2)), expected);
52 }
53
54
55 #[test]
56 #[ignore]
57 fn change_in_type() {
58 let input: Vec<&str> = vec!["1", "2", "3"];
59 let expected: Vec<String> = vec!["1".into(), "2".into(), "3".into()];
60 assert_eq!(map(input, |s| s.to_string()), expected);
61 }
62
63 #[test]
64 #[ignore]
65 fn mutaing_closure() {
66 let mut counter = 0;
67 let input = vec![-2, 3, 4, -5];
68 let expected = vec![2, 3, 4,5];
69 let result = map(input, |x:i64| {
70 counter += 1;
71 x.abs()
72 });
73 assert_eq!(result, expected);
74 assert_eq!(counter, 4);
75 }
76
77 #[test]
78 #[ignore]
79 fn minimal_bounds_on_input_and_output() {
80 // mut be able to accept arbitrary input and output types
81 struct Foo;
82 struct Bar;
83 map(vec![Foo], |_| Bar);
84 }
FnOnce , FnMut <RUST>的更多相关文章
- FnOnce,FnMut和Fn
继承结构 FnOnce FnMut: FnOnce Fn: FnMut FnOnce就是说会转移闭包捕获变量的所有权,在闭包前加上move关键字可以限定此闭包为FnOnce move关键字是强制让环境 ...
- 【译】理解Rust中的闭包
原文标题:Understanding Closures in Rust 原文链接:https://medium.com/swlh/understanding-closures-in-rust-21f2 ...
- 闭包类型(Fn,FnMut,FnOnce)和move关键字
move关键字是强制让环境变量的所有权转移到闭包中而不管是不是发生了所有权的转移 move关键字和匿名函数是否是FnOnce没有必然联系,之和匿名函数体有关 当匿名函数体里转移了环境变量的所有权的时候 ...
- Tokio,Rust异步编程实践之路
缘起 在许多编程语言里,我们都非常乐于去研究在这个语言中所使用的异步网络编程的框架,比如说Python的 Gevent.asyncio,Nginx 和 OpenResty,Go 等,今年年初我开始接触 ...
- rust 高级话题
目录 rust高级话题 前言 零大小类型ZST 动态大小类型DST 正确的安装方法 结构体 复制和移动 特征对象 引用.生命周期.所有权 生命周期 错误处理 交叉编译 智能指针 闭包 动态分派和静态分 ...
- rust语法
目录 rust语法 前言 一.数据类型 1.1 标量scalar 1.2 复合compound 1.3 切片slice 1.4 引用(借用)reference 1.5 智能指针smart pointe ...
- Rust基础笔记:闭包
语法 Closure看上去是这样的: let plus_one = |x: i32| x + 1; assert_eq!(2, plus_one(1)); 首先创建一个绑定plus_one,然后将它分 ...
- 【译】理解Rust中的Futures(二)
原文标题:Understanding Futures in Rust -- Part 2 原文链接:https://www.viget.com/articles/understanding-futur ...
- the rust book 的简单入门笔记
rust learning day 1 (2021/05/27) 学了常量,变量,数据类型,控制流,所有权 char 的宽度是4字节,一个 unicode 的宽度 控制流条件都不要括号 rust 中的 ...
- Writing A Threadpool in Rust
文 Akisann@CNblogs / zhaihj@Github 本篇文章同时发布在Github上:https://zhaihj.github.io/writing-a-threadpool-in- ...
随机推荐
- jquery中判断复选框有没有被选上
页面部分: <input type="checkbox" id="cbx" /><label for="cbx">点 ...
- idea的上git的拉取推送
下载好idea和git idea的下载破解查看https://www.cnblogs.com/badfisher/p/14709120.html git官网要求下载即可. 获取仓库路径点击复制. 在i ...
- python实现远程桌面
项目旨在让大家理解远控软件的原理,通过远控桌面可以实现远程控制我们的电脑,更好更方便的管理电脑.文末将给出初始版的完整代码,需要使用到的其他工具也会有所说明.最终实现的效果就是只要用户点击了客户端的程 ...
- [Shell] Windows上支持Linux Shell的工具/方法
0 概述 1 方式一 : Windows Terminal 局限性: 不支持 xargs等命令 支持sed,find等命令 安装方式 安装Windows Terminal的最简单方法是通过Micros ...
- [软件过程/软件生命周期模型]软件过程的工具链&技术链【待续】
0 宣言:DevOps & RUP统一过程建模 1 项目管理 (需求管理 / 缺陷管理 / ...) 禅道(前身:bugfree) [在线协作] JIRA(项目与事务跟踪工具) 与禅道类同,但 ...
- [设计模式/网络/WebServer/Nginx]设计模式之代理模式(网络代理 : 正向代理与反向代理)【7】
1 代理模式 1.1 模式定义 代理模式(Proxy Pattern):为其他对象提供一种代理服务以对这个被代理的对象进行控制访问.[ 设计模式.面向对象程序设计思想的鼻祖----GoF] Subje ...
- ModelAndView方法的返回值类型
一.ModelAndView @RequestMapping("/selectById") public ModelAndView queryById(Integer id){ M ...
- 四月十二号java基础知识
1.面向对象的编程思想是力图使在计算机语言中对事物的描述与现实世界中该事物的本来面目尽可能地一致.2.类(class)和对象(object)是面向对象程序设计方法中最核心的概念3.类是对某一事物的描述 ...
- 通过命令快速找到python的路径
查询Python 首先我们需要知道Python安装路径,可以在命令行中逐行执行下面代码 python3 import sys sys.executable
- X配置文件xorg.conf分析
X配置文件xorg.conf分析 转载于:http://blog.csdn.NET/comcat/archive/2007/04/02/1549658.aspx 作者:壮志凌云的csdn博客 X的配置 ...