首页 > 解决方案 > 迭代 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()
}

迭代 a怎么样Vec<String>for (i, item) infor (i, &item) in? _

编辑

这是版本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()
}

标签: rust

解决方案


您的两个代码片段在语义上是等效的。如果您:

  • 通过解构引用(i, &item),然后item直接使用,或者
  • item每次使用都取消引用*item

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

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

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


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

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

改进:

  • String::bytes是一种更简单的迭代字符串字节的方法
  • Iterator::positionfor已经实现了你的循环正在实现的逻辑
  • unwrap_or是提供后备的理想选择

推荐阅读