为什么是斐波那契数列

斐波那契数列十分适合用来实战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. Codeforces 931D:Peculiar apple-tree

    D. Peculiar apple-tree time limit per test : 1 second memory limit per test : 256 megabytes input : ...

  2. ADAM : A METHOD FOR STOCHASTIC OPTIMIZATION

    目录 概 主要内容 算法 选择合适的参数 一些别的优化算法 AdaMax 理论 代码 Kingma D P, Ba J. Adam: A Method for Stochastic Optimizat ...

  3. kotlin+springboot+mybatis-puls+mysql搭建gradle-web工程

    kotlin+springboot+mybatis-puls+mysql搭建web工程 ​ 前段时间研究了spring security及OAuth2系列之后,本来打算研究spring的,但是部门发生 ...

  4. <学习opencv>图像变换

    拉伸.收缩.扭曲和旋转 统一调整大小 我们经常会遇到一些我们希望转换为其他尺寸的图像. 我们可能想要扩大或缩小图像; 这两项任务都是由同一个功能完成的. cv::resize() 该cv::resiz ...

  5. Capstone通用 USB Type-C音视频拓展坞转换芯片

    专业解决视频接口技术Capstone科技在2021年新推出四款低功耗单芯片USB Type-C音视频格式转换器方案──CS5266.CS5267.CS5268与CS5269.将为各种显示屏.外部显示设 ...

  6. 使用 DML语句,对 “锦图网” 数据进行操作,聚合函数练习

    查看本章节 查看作业目录 需求说明: 根据客户 ID 统计订单数.订单总金额.最高订单金额.最低订单金额和每份订单平均金额,并按订单总金额升序显示 根据客户统计订单总订购人次数> 5 的统计信息 ...

  7. Java+HTML5 试题 云南农业职业技术学院 - 互联网技术学院

    摸底测试 100题_共100.00分_及格60.00分  第1题 [单选题][1.00分][概念理解] 执行完下面程序片段后, ( )的结论是正确的. int a, b, c; a = 1; b = ...

  8. Drools创建Maven工程

    1.说明 本文介绍创建Drools的Maven工程的方法, 仅使用Eclipse开发工具, 不使用Drools的相关插件, 先创建一个Maven工程, 然后引入Drools的相关依赖即可, 最后再写一 ...

  9. 【java多线程】synchronized和volatile

    文章目录 一.synchronized 1.synchronized使用的方法 2.注意 3.不要以字符串作为锁的对象 4.`synchronized`锁的是什么? 二.volatile 1.引出问题 ...

  10. Typescript 字符串字面量类型

    字符串字面类型定义的类型是固定的,在其使用时必须是其定义的其中一个字符串,否则会报错 当传入一个定义之外的字符串时,会报错字符串字面量类型.ts(13,20): error TS2345: Argum ...