迭代Rust Vec的首选方法?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代Rust Vec的首选方法?相关的知识,希望对你有一定的参考价值。

使用以下代码,first_word2()first_word1()好,因为它不复制项目?

fn first_word1(s: &String) -> usize 
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() 
        if item == b' ' 
            return i;
        
    

    s.len()


fn first_word2(s: &String) -> usize 
    let bytes = s.as_bytes();

    for (i, item) in bytes.iter().enumerate() 
        if *item == b' ' 
            return i;
        
    

    s.len()

Vec<u8>的首选解决方案是(i, item)(而不是(i, &item)),迭代Vec<String>呢?

编辑

这里是Vec<String>的版本:

fn find_space1(v: &Vec<String>) -> usize 
    for (i, &item) in v.iter().enumerate() 
        if item == " " 
            return i;
        
    
    v.len()


fn find_space2(v: &Vec<String>) -> usize 
    for (i, item) in v.iter().enumerate() 
        if item == " " 
            return i;
        
    
    v.len()

答案

您的两个代码段在语义上都是等效的。没关系,如果您:

  • 通过(i, &item)分解参考,然后直接使用item,或
  • 每次使用时都像item一样引用*item

它们将编译为相同的机器代码,因此速度或其他方面没有差异。优先选择另一个的唯一原因是:您必须输入多少。例如,如果您的条件为item == b' ' || item == b'_',那么我想说解构(i, &item)解决方案更好,因为您只需要一个&而不是两个*

如果Vec<u8>的首选解决方案是(i, item)(而不是(i, &item),那么迭代Vec<String>呢?

您不能将任何一个版本与String一起使用,因为它没有实现Copy。但是您也不需要复制/克隆它来进行比较。当s == " "s时,&String可以正常工作。


独立于您的问题,您可以通过另一种方式来改进代码:通过使用迭代器链。

fn first_space(s: &String) -> usize 
    s.bytes().position(|b| b == b' ').unwrap_or(s.len())

改进:

  • String::bytes是遍历字符串字节的更简单方法
  • [Iterator::position已经实现了for循环正在实现的逻辑
  • unwrap_or是提供后备的理想选择

以上是关于迭代Rust Vec的首选方法?的主要内容,如果未能解决你的问题,请参考以下文章

rust - 方法 `draw`存在,但在Vec <Box <dyn Trait >>中不满足以下特征范围,Compilernote应该满足吗?

如何迭代 Rust 中序列的所有唯一排列?

将对元组的引用的迭代器解压缩为两个引用集合

在 Rust 中迭代、过滤和映射数据从一个结构到另一个结构

Rust:如何在第一个 Err 或 None 上短路退出迭代器方法链?

Rust性能分析-迭代器的enumerate方法是否会影响程序性能