代码之家  ›  专栏  ›  技术社区  ›  Harry

如何获取两个迭代器之间的距离:C++等价于std::distance

  •  0
  • Harry  · 技术社区  · 4 月前

    我试图得到两个迭代器之间的距离(C++等价于 std::distance ). 但根据下面的代码逻辑,我无法做到。

    fn main() {
        let list = vec![1, 3, 5, 7, 9, 11, 11, 11, 11, 13, 15, 17, 19];
        for x in list.iter().skip(3).take(100) {
            print!("{}, ", x);
        }
        println!();
        
        let itr1 = list.iter().enumerate().next();
        let itr2 = list.iter().skip(5).enumerate().next();
        
        if itr1.is_some() && itr2.is_some() {
            println!("{}: {}", itr1.unwrap().0, itr1.unwrap().1);
            println!("{}: {}", itr2.unwrap().0, itr2.unwrap().1);
            
            let d = itr2.unwrap().0 - itr1.unwrap().0;
            println!("{}", d); // prints 0
        }
    }
    
    2 回复  |  直到 4 月前
        1
  •  1
  •   Jmb    4 月前

    现在,每个迭代器都从其起点开始计数。只需拨打电话,让他们从同一点开始计数 enumerate 之前 你开始移动(例如 skip ):

    fn main() {
        let list = vec![1, 3, 5, 7, 9, 11, 11, 11, 11, 13, 15, 17, 19];
        for x in list.iter().skip(3).take(100) {
            print!("{}, ", x);
        }
        println!();
        
        let itr1 = list.iter().enumerate().next();
        let itr2 = list.iter().enumerate().skip(5).next();    // <-- change this line
        
        if itr1.is_some() && itr2.is_some() {
            println!("{}: {}", itr1.unwrap().0, itr1.unwrap().1);
            println!("{}: {}", itr2.unwrap().0, itr2.unwrap().1);
            
            let d = itr2.unwrap().0 - itr1.unwrap().0;
            println!("{}", d); // prints 0
        }
    }
    

    playground

        2
  •  -2
  •   Optimistic Peach    4 月前

    Rust迭代器与C++迭代器截然不同。相反,它们更接近C++的范围和视图。

    事实上,Rust迭代器是比简单指针更复杂的对象。一些迭代器当然在内部实现为指针,例如 std::slice::Iter ,但是,这些是您(通常)不能依赖的实现细节。

    相反,你可以使用一些工具来实现你想做的事情 std::distance 例如,如果你想知道迭代器有多远,你可以对其进行转换,以计算它正在使用的项目有多远 .enumerate() :

    let items = vec!["a", "b", "c"];
    
    for (idx, item) in items.iter().enumerate() {
        println!("{idx} yields {item}");
    }
    

    印刷品

    0 yields a
    1 yields b
    2 yields c
    

    事实上,工具的具体选择取决于你试图实现的确切目标。