Skip to content

[Practice] 为什么出现了预料之外的结果? #4

Description

@ZhangHanDong
fn main() {
    let a = [1, 2, 3];
    let mut iter = a.iter();    
    assert_eq!(iter.any(|&x| x != 2), true);
    let sum = iter.fold(0, |acc, &x| acc + x);
    assert_eq!(sum, 6);
}

此代码运行报错:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `5`,
 right: `6`', src/main.rs:6:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

请解释,为什么会出现这种错误?

——————

考察点:迭代器

Activity

  1. huangjj27 commented on Nov 24, 2017

    @huangjj27

    标题错误: "语料"应为"预料"

  2. ZhangHanDong commented on Nov 24, 2017

    @ZhangHanDong
    ContributorAuthor

    @huangjj27 啊偶。。

  3. changed the title [-][Practice] 为什么出现了语料之外的结果?[/-] [+][Practice] 为什么出现了预料之外的结果?[/+] on Nov 24, 2017
  4. huangjj27 commented on Nov 24, 2017

    @huangjj27

    我们注意到, main函数体第二行定义了一个将在后面两个语句中均用到的迭代器iter: 在第一次用到iter变量的语句中iter.any(|&x| x != 2)将会在a元素为1处返回true, 也就是执行了一次iter.next(); 而在rust里面, 迭代器是惰性的, 这意味者, 再次使用iter变量, 并不会重头再迭代, 而是在上次停留的地方开始迭代! 所以, 在函数体第4行中开始fold运算时, 获得第一个&x是前面运行结果再次iter.next()的结果, 也就是2, 然后才是3, 最后没有元素结束.
    所以实际结果是0 + 2 + 3 = 5.

    为了达到预期结果, 将函数体第3行注释, 或者第四行改为:

    let sum = a.iter().fold(0, |acc, &x| acc + x);  // 另外创建一个新的迭代器, 这个迭代器将重头开始迭代.

    答题要点:

    1. 迭代器是惰性的
    2. 同一个迭代器多次通过不同的方法操作
  5. ZhangHanDong commented on Nov 24, 2017

    @ZhangHanDong
    ContributorAuthor

    @huangjj27 bingo!

  6. huangjj27 commented on Feb 6, 2018

    @huangjj27

    问题Answered~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions