V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
0gre2019
V2EX  ›  Rust

std::iter::iterator::size_hint 方法究竟实现了个什么功能头好晕

  •  
  •   0gre2019 · 2020-09-22 17:17:42 +08:00 · 2920 次点击
    这是一个创建于 1530 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先官方文档描述为,返回当前迭代器未迭代元素数量的上下界。

    首先这个定义就很迷惑,什么叫未迭代元素数量的上下界。。未迭代元素数量不应该是确定的一个值吗 <即使是一个类似于 (let x = (0..); 的无限迭代器,也应该是一个确定的值‘infinite’或者 None 吧?>

    回到文档,具体实现是返回一个 tuple (usize, Option<usize>) ,左边表示下界,右边表示上界。

    然后再看下官方给的例子:

    • 一个基础样例: let a = [1, 2, 3]; let iter = a.iter();

      assert_eq!((3, Some(3)), iter.size_hint());

    从这段代码来看,由于 iter 的 next 未被调用,所以 iter 的未迭代元素数量是 3

    然后看一下 size_hint 的返回值,(3, Some(3))是什么意思,是一种来自编译器的‘推测’吗?我的理解是,编译器推测出‘未迭代元素数量的最小值’为 3,因为我们已经确定了 iter 甚至并未开始工作;然后编译器推测出‘未迭代元素数量的最大值’也为 3,这我也能理解。

    • 一个复杂点的样例:

      // 过滤出 0..10 中的偶数.则 iter 的内容应该是(0, 2, 4, 6, 8)

      let iter = (0..10).filter(|x| x % 2 == 0);

      // 凭什么??这个 0 和 10 代表什么?按我的理解还有 5 个元素未迭代,怎么会有个 10 呢。。

      assert_eq!((0, Some(10)), iter.size_hint());

      // 用 chain 适配器在之后接上五个值,那么应该为(0 2 4 6 8 15 16 17 18 19)

      let iter = (0..10).filter(|x| x % 2 == 0).chain(15..20);

      // 为什么上下界同时加 5 ??这里 5 和 15 又代表什么呢??

      assert_eq!((5, Some(15)), iter.size_hint());

    实在太困惑了,看了一个多小时愣是没看懂。如果这个方法真的是一种‘推测’功能,它是凭什么来推测的呢?

    1 条回复    2020-10-09 21:20:59 +08:00
    PTLin
        1
    PTLin  
       2020-10-09 21:20:59 +08:00
    这个 size_hint 就是为一些创建集合的函数提供一些基本信息,比如 FromIterator trait,这个信息也许可以辅助 from_iter 一类的方法在创建分配连续内存的时候可以直接分配个适当的大小。
    至于为什么 filter,chain 的 size_hint 会是那些值其实直接看源码就行了,不是什么编译器预测的。。。
    https://doc.rust-lang.org/src/core/iter/adapters/mod.rs.html#996
    https://doc.rust-lang.org/src/core/iter/adapters/chain.rs.html#160
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2582 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 03:31 · PVG 11:31 · LAX 19:31 · JFK 22:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.