为什么是斐波那契数列

斐波那契数列十分适合用来实战rust的迭代器,算法也很简单,一目了然。这个例子可以用来学习Iterator的使用,十分适合刚学习了rust的迭代器章节后用来练练手。

代码实战

don't bb, show me the code

struct Fib(usize, usize);

impl Fib {
fn new() -> Fib {
Fib(0, 1)
}
} impl Iterator for Fib {
type Item = usize;
fn next(&mut self) -> Option<usize> {
*self = Fib(self.1, self.0 + self.1);
Some(self.0)
}
} fn main() {
let last = 20;
println!("fib({}) result: {:?}", last, Fib::new().take(last).collect::<Vec<usize>>());
}

分解知识点

  1. 代码定义了一个名字为Fib的元组结构体(tuple structs)。因为我们的实现封装了实现细节,没必要定义一个具名结构体。

    网上有给出其他定义了名称的结构体,个人觉得有点多余了。比如这样
struct Fibonacci {
a: u64,
b: u64,
}
  1. 第二点就是如何实现Iterator,关键就两点,定义关联类型和实现next方法
impl Iterator for Fib {
// 1. 定义关联类型为usize
type Item = usize;
// 2. 实现next方法,这里也是主要的逻辑
fn next(&mut self) -> Option<usize> {
*self = Fib(self.1, self.0 + self.1);
Some(self.0)
}
}
  1. 第三点是*self = Fib(self.1, self.0 + self.1);; self被定义为了可变引用(&mut), 这里*self 解引用为Fib类型。

    另外一种写法
self = &mut Fib(self.1, self.0 + self.1);

上面定义了一个可变引用 &mut Fib 赋值给self,rust编译器直接提示

   |
12 | self = &mut Fib(self.1, self.0 + self.1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot assign to immutable argument error[E0716]: temporary value dropped while borrowed
--> src\main.rs:12:21
|
11 | fn next(&mut self) -> Option<usize> {
| - let's call the lifetime of this reference `'1`
12 | self = &mut Fib(self.1, self.0 + self.1);
| ------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| assignment requires that borrow lasts for `'1`

提示借用了临时变量,临时变量会被丢弃掉。其实就是&mut Fib 只是一个可变借用,在被借用给self后就会马上失效了,self就会指向一个悬垂指针, rust编译器肯定不会让这种情况发生的(强行解释一波,欢迎打脸)。

所以正确的做法是直接让self获取新创建的Fib的所有权就行了。也就是*self = Fib(self.1, self.0 + self.1);

  1. 第四点是Fib::new().take(last).collect::<Vec<usize>>()。 这里直接在println宏里打印结果,编译器推断不出需要collect的类型,需要使用collect::标注。

    除非是下面这种写法,编译器能自动推断出来

let result: Vec<usize> = Fib::new().take(last).collect();
println!("fib({}) result: {:?}", last, result);

总结

本文通过rust iterator来实现斐波那契数列,需要掌握一下要点

  • 元组结构体写法
  • 如何实现iterator trait
  • collect:: 帮助编译器推断类型


rust实战系列 - 使用Iterator 迭代器实现斐波那契数列(Fibonacci )的更多相关文章

  1. python实现斐波那契数列(Fibonacci sequence)

    使用Python实现斐波那契数列(Fibonacci sequence) 斐波那契数列形如 1,1,2,3,5,8,13,等等.也就是说,下一个值是序列中前两个值之和.写一个函数,给定N,返回第N个斐 ...

  2. 斐波那契数列(Fibonacci) iOS

    斐波那契数列Fibonacci 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2 ...

  3. 使用一位数组解决 1 1 2 3 5 8 13 数列问题 斐波纳契数列 Fibonacci

    斐波纳契数列 Fibonacci 输出这个数列的前20个数是什么? 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 使用数组实现输出数列的前30 ...

  4. 使用并行的方法计算斐波那契数列 (Fibonacci)

    更新:我的同事Terry告诉我有一种矩阵运算的方式计算斐波那契数列,更适于并行.他还提供了利用TBB的parallel_reduce模板计算斐波那契数列的代码(在TBB示例代码的基础上修改得来,比原始 ...

  5. Go斐波拉契数列(Fibonacci)(多种写法)

    1 前言 斐波拉契数列有递归写法和尾递归和迭代写法. 2 代码 //recursion func fib(n int) int{ if n < 2{ return n }else{ return ...

  6. poj3070_斐波那契数列(Fibonacci)

    用矩阵求斐波那契数列,快速幂log(n),只用求最后4位(加和乘的运算中前面的位数无用) #include <stdio.h> #include <stdlib.h> int ...

  7. 练习六:斐波那契数列(fibonacci)

    题目:斐波那契数列. 程序分析:斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.……. 在数学上,斐波那契数列 ...

  8. Java实现斐波那契数列Fibonacci

    import java.util.Scanner; public class Fibonacci { public static void main(String[] args) { // TODO ...

  9. k阶斐波那契数列fibonacci第n项求值

    已知K阶斐波那契数列定义为:f0 = 0,  f1 = 0, … , fk-2 = 0, fk-1 = 1;fn = fn-1 + fn-2 + … + fn-k , n = k , k + 1, … ...

随机推荐

  1. 1742 开心的小Q

    如果一个数字存在一个约数是完全平方数,那么小Q就认为这个数是有趣的. 小Q喜欢收集有趣的数字,每找到一个有趣的数,小Q就会变得很开心. 小Q发现12是有趣的,18也是有趣的,它们都是36的约数,而在3 ...

  2. netty系列之:从零到壹,搭建一个SOCKS代理服务器

    目录 简介 使用SSH搭建SOCKS服务器 使用netty搭建SOCKS服务器 encoder和decoder 建立连接 ConnectHandler 总结 简介 上一篇文章,我们讲到了netty对S ...

  3. 美和易思 MOOT去鼠标检测,快进,倍速,自动下一章

    F12 放到 console 直接运行即可 或者油猴添加新脚本 核心去除网页绑定焦点事件代码: if (!-[1,] && !window.XMLHttpRequest || navi ...

  4. 使用 JavaScript 的 HTML 页面混合、JavaScript 文件引用和 HTML 代码嵌入 3 种方式在 HTML 页面上打印出“点击我进入到百度首页”的超链接

    查看本章节 查看作业目录 需求说明: 使用 JavaScript 的 HTML 页面混合.JavaScript 文件引用和 HTML 代码嵌入 3 种方式在 HTML 页面上打印出"点击我进 ...

  5. Java高级大一结业认证考试试题 - 云南农业职业技术学院 - 互联网技术学院 - 美和易思校企合作专业

     第1题 .关于XML的文档结构描述错误的是 一个基本的XML文档通常由序言和文档元素两部分组成 XML文档中的序言可以包括XML声明.处理指令和注释 XML文档中的元素以树形结构排列 XML文档的声 ...

  6. Kafka基础教程(三):C#使用Kafka消息队列

    接上篇Kafka的安装,我安装的Kafka集群地址:192.168.209.133:9092,192.168.209.134:9092,192.168.209.135:9092,所以这里直接使用这个集 ...

  7. Java常用的几种设计模式

    本来想写点spring相关的东西的,想来想去,先写点设计模式的东西吧 什么是设计模式?套用百度百科的话解释吧 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设 ...

  8. nano 编辑器快速入门

    # 打开或新建一个文件 $ nano tmp.txt # 常用组合按键 ^G:获取帮助 ^X:退出,如果文件有改定会提示是否保存 ^O:保存文件内容 ^R:读取其他文件的内容,放入到当前文件中 ^W: ...

  9. PowerShell 【按任意键继续】

    1 function Pause(){ 2 [System.Console]::Write('按任意键继续...') 3 [void][System.Console]::ReadKey(1) 4 } ...

  10. js对cookie的操作:读、写、删

    js读写cookie //JS操作cookies方法!//写cookiesfunction setCookie(name,value){var Days = 30;var exp = new Date ...