rust_interview icon indicating copy to clipboard operation
rust_interview copied to clipboard

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

Open ZhangHanDong opened this issue 8 years ago • 5 comments
trafficstars


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.

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

——————

考察点:迭代器

ZhangHanDong avatar Oct 31 '17 11:10 ZhangHanDong

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

huangjj27 avatar Nov 24 '17 12:11 huangjj27

@huangjj27 啊偶。。

ZhangHanDong avatar Nov 24 '17 12:11 ZhangHanDong

我们注意到, 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. 同一个迭代器多次通过不同的方法操作

huangjj27 avatar Nov 24 '17 13:11 huangjj27

@huangjj27 bingo!

ZhangHanDong avatar Nov 24 '17 13:11 ZhangHanDong

问题Answered~

huangjj27 avatar Feb 06 '18 15:02 huangjj27