【问题标题】:How to iterate over an array of integers?如何遍历整数数组?
【发布时间】:2015-04-07 08:11:24
【问题描述】:

如何在 Rust 中迭代整数数组?

fn main () {

    let mut array: Vec<i64> = vec![2];

    for k in range(3, 13195) {
        for p in array.iter() {
           if (k % p != 0) {array.push(p)};
        }        
    }
}

给我编译器错误:

rustc "Task2_minimalcode.rs" (im Verzeichnis: C:\Users\XXX\Documents\Rust - Project Euler)

Task2_minimalcode.rs:7:14: 7:15 错误:类型不匹配: 预期_, 找到&amp;i64 (预期的积分变量, 找到 &-ptr) [E0308] Task2_minimalcode.rs:7 if (k % p != 0) {array.push(p)};
^ Task2_minimalcode.rs:7:34: 7:35 错误:类型不匹配: 预期i64, 找到&amp;i64 (预计 i64, 找到 &-ptr) [E0308]

Task2_minimalcode.rs:7 if (k % p != 0) {array.push(p)}; ^ 错误:由于 2 个先前的错误而中止 编译失败。

【问题讨论】:

    标签: arrays iteration rust


    【解决方案1】:

    报错信息:

    error: mismatched types: expected i64, found &amp;i64 (expected i64, found &amp;-ptr)

    Vec&lt;T&gt;::iter 为您提供&amp;T 的迭代器(对T 的引用)。如果您不打算再次使用 vec,可以使用 for p in arrayfor p in array.into_iter()。如果您确实想再次使用它,您有多种选择:

    • &amp;arrayarray.iter(),并在使用时取消引用 p
    • array.iter().cloned()
    • array.iter().map(|e| *e)(实际上和上面一样)

    如果所有这些关于引用的讨论没有意义,您可能应该阅读Rust Book on Pointers 的部分。

    请记住,您可以欺骗编译器告诉您变量的类型,如下所示:let _:() = p; -- 错误消息将包含真实类型。

    【讨论】:

    • 我再次需要那个向量。 “使用时取消引用 p。”我怎么做? &p 不起作用
    • &amp;p 引用 p*p 取消引用 p。您可能应该通读 Rust Book;如果不了解 Rust 中的引用,你不会走得太远:它们无处不在。
    • 我知道什么是引用/解除引用,但是来自托管代码 (Java) 我很难决定何时何地使用它:(。
    • 这就是我推荐这本书的原因;这不是要知道它们在抽象中是什么,您需要了解它们是如何使用的。
    【解决方案2】:

    当您遍历切片(这是Vec 的视图)时,您将获得对向量中项目的引用,而不是项目本身。

    您可以通过两种等效的方式解决此问题。

    // Mark the iteration variable as a reference
    for &p in &array {
        if (k % p != 0) {
            array.push(p)
        };
    }
    
    // Dereference the iteration variable
    for p in &array {
        if (k % *p != 0) {
            array.push(*p)
        };
    }
    

    但是,您会遇到下一个问题:您无法在迭代 Vec 时对其进行修改!如果您被允许,向量可能需要重新分配支持它的内存,这反过来又会使 迭代器中的所有引用无效。这是 Rust 的一个强大卖点——它可以防止你像这样在自己的脚上开枪!

    在不知道你真正想做什么的情况下,这里有一种方法:

    fn main() {
        let input_array = vec![2u64];
        let mut output_array = input_array.clone();
    
        for k in 3..13195 {
            for &p in &input_array {
                if k % p != 0 {
                    output_array.push(p)
                };
            }
        }
    }
    

    另见:

    【讨论】:

    • 我的目标是 Euler 项目任务 3 (projecteuler.net/problem=3),但似乎我需要获得更好的算法。我会过度考虑我的程序,谢谢你的帮助:)。
    • 据我了解,切片将产生i32 类型的值,对吗?我想要一片usize 值,如何指定?
    • @ArtemHevorhian 切片返回任何类型的值。在本例中,它是Vec&lt;u64&gt;,因此子切片和索引值也将使用u64。更改切片的类型以更改子切片和索引值。
    猜你喜欢
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-29
    • 2014-10-23
    • 2018-10-05
    相关资源
    最近更新 更多