深入Rust 迭代器之 std::iter::iterator::size_hint() 方法

yufei       1 月, 2 周 前       48

Rust 语言的迭代器有这么一个方法 std::iter::iterator::size_hint() 方法,它的返回值对于大部分人来说真的是一个迷。

首先,我们看看 官方给的解释

Returns the bounds on the remaining length of the iterator.

Specifically, size_hint() returns a tuple where the first element is the lower bound, and the second element is the upper bound.

The second half of the tuple that is returned is an Option<usize>. A None here means that either there is no known upper bound, or the upper bound is larger than usize.

翻译成中文就是

size_hint() 返回当前迭代器未迭代元素数量的上下界。

具体来说,size_hint() 返回的是元组,元组的第一个元素是未迭代元素数量的下界,第二个元素是未迭代元素的上界。

size_hint() 返回的元素的第二个元素的值是一个 Option<usize> ,原因是上界有可能是不可预测的。如果上界不可预知,那么就会返回 None,如果上界的值大于 usize 所能表示的最大的值,返回的也是 None

相信官方已经说的很清楚了,也很好理解了。

但实际上有些行为是有点奇怪的。

比如

let a = [1, 2, 3]; 
let iter = a.iter();
assert_eq!((3, Some(3)), iter.size_hint());

数组 [1, 2, 3] 的长度是已知的,由于未开始迭代,所以上界和下界都是 3,这就是 (3, Some(3) 的由来。

但是,请看下面的代码

// 过滤出 0..10 中的偶数.则 iter 的内容应该是(0, 2, 4, 6, 8)
let iter = (0..10).filter(|x| x % 2 == 0);
assert_eq!((0, Some(10)), iter.size_hint());

如果按照上面的值,这里应该是 (0,some(5)) 才对,但是返回的结果竟然是 (0,some(10)),为什么呢?

原因就是:size_hint() 未迭代数量的上界在创建迭代器之前就计算好了。它并不会发生任何迭代器求值行为。

回忆一下,我们实现一个迭代器接口的时候是不是只要实现 next() 方法,而且大家都知道,迭代器是不能重复调用的。因此,对未迭代元素的上界判定只能是迭代器创建时就界定好了。

另一个原因,迭代器是惰性求值的,所有产生迭代器的方法都是惰性求值的。

因此 filter() 方法并不会一次性把所有元素都过滤好,然后生成一个迭代器,而是要每次调用 next() 方法时才会去判断条件,这也是如果要取得 filter() 方法的所有元素,必须 filter().collect() 的原因才能得到完整的过滤列表的原因。

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2018 简单教程 twle.cn All Rights Reserved.