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>的更多相关文章

  1. FnOnce,FnMut和Fn

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

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

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

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

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

  4. Tokio,Rust异步编程实践之路

    缘起 在许多编程语言里,我们都非常乐于去研究在这个语言中所使用的异步网络编程的框架,比如说Python的 Gevent.asyncio,Nginx 和 OpenResty,Go 等,今年年初我开始接触 ...

  5. rust 高级话题

    目录 rust高级话题 前言 零大小类型ZST 动态大小类型DST 正确的安装方法 结构体 复制和移动 特征对象 引用.生命周期.所有权 生命周期 错误处理 交叉编译 智能指针 闭包 动态分派和静态分 ...

  6. rust语法

    目录 rust语法 前言 一.数据类型 1.1 标量scalar 1.2 复合compound 1.3 切片slice 1.4 引用(借用)reference 1.5 智能指针smart pointe ...

  7. Rust基础笔记:闭包

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

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

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

  9. the rust book 的简单入门笔记

    rust learning day 1 (2021/05/27) 学了常量,变量,数据类型,控制流,所有权 char 的宽度是4字节,一个 unicode 的宽度 控制流条件都不要括号 rust 中的 ...

  10. Writing A Threadpool in Rust

    文 Akisann@CNblogs / zhaihj@Github 本篇文章同时发布在Github上:https://zhaihj.github.io/writing-a-threadpool-in- ...

随机推荐

  1. JsonCpp JSON格式处理库的介绍和使用(面向业务编程-文件格式处理)

    JsonCpp JSON格式处理库的介绍和使用(面向业务编程-文件格式处理) 介绍 JSON是一种轻量级的数据交换格式,它是一种键值对的集合.它的值可以是数字.字符串.布尔值.序列. 想知道更多有关J ...

  2. Centos9网卡配置

    Centos9 网卡配置文件已修改,如下 [root@bogon ~]# cat /etc/NetworkManager/system-connections/ens18.nmconnection [ ...

  3. C# 通过一个控制台打开另一个控制台

    现有个需求是通过一个主程序获取配置的线程数和进程数打开连一个控制台程序,将线程数和系统编码作为参数传给控制台程序. 下面附上Demo. 1 private static void Main(strin ...

  4. Java语言在Spark3.2.4集群中使用Spark MLlib库完成朴素贝叶斯分类器

    一.贝叶斯定理 贝叶斯定理是关于随机事件A和B的条件概率,生活中,我们可能很容易知道P(A|B),但是我需要求解P(B|A),学习了贝叶斯定理,就可以解决这类问题,计算公式如下: P(A)是A的先验概 ...

  5. Redis(四)主从复制

    主从复制 简介 主机数据更新之后根据配置和策略,自动同步数据到备机的Master/Slaver机制,Master以写为主,Slaver以读为主. 这样的机制能够实现: 读写分离:Master以写为主, ...

  6. 理解Java程序的执行

    main 方法 public class Solution { public static void main(String[] args) { Person person = new Person( ...

  7. Jquery实现复选框的选中和取消

    复选框的选中与取消 我在网上看了好多关于这个问题的解答,好多都是一两个按钮的触发事件,有的甚至没有任何效果,经过自己的调试发现这个方法好用一点: 首先我在页面上添加了这样一个复选框 我的复选框是动态加 ...

  8. react项目使用less样式,配置less

    create-react-app脚手架创建的项目有sass配置项,使用的时候只需要装包即可,下面是less使用的方法 由于 create-react-app 脚手架中并没有配置关于 less 文件的解 ...

  9. react异常 Each child in a list should have a unique “key” prop

    react异常警告:Each child in a list should have a unique "key" prop 原因:Dom在渲染数组时,需要一个key,不然嵌套数组 ...

  10. ABC294Ex K-Coloring

    Statement 对一张简单无向图进行 \(k\) 染色,满足对于每条边的两个端点颜色不同,求方案数. \(n,m\leq 30\). Solution 无向图 \(k\) 染色问题,很经典的问题. ...