填充一个数组“let x = [1..11],在不同的函数中多次迭代它?

Fill an array "let x = [1..11], iterate over it multiple times in different functions?

我正在为一个简单的问题寻找一个简单而不臃肿的解决方案。

代码(playpen):

use std::ops::Range;

// Sum of square numbers from 1 to 10 # 1^2 + 2^2 + 3^2 ...
fn sum_square(v: &[i64; 10]) -> i64 {
    let mut sum: i64 = 0;
    for x in v {
        sum += x * x;
    }
    return sum;
}


// Square sum of the added numbers from 1 to 10 # (1+2+3+...)^2
fn square_sum(v: &[i64; 10]) -> i64{
    let mut sum: i64 = 0;
    for x in v {
        sum += x;
    }
    return sum*sum;
}

fn main() {
    let v: [i64; 10] = [1,2,3,4,5,6,7,8,9,10];
    let diff = sum_square(&v) - square_sum(&v);
    println!("{}", diff);
}

我在 main 函数中有一个数组,其中填充了 1-10 的数字(是的,我知道 [1..11] 不起作用,但最好的解决方案是什么?使用 "range" 是不行的毫无疑问,我想要一个数组而不必键入每个数字)。 现在我需要在不同的函数中多次迭代这个数组(这里是 2x)。

我不想使用 .copy()(因为我不想移动),我想将数组借用给函数,如下所述:http://imgur.com/xMDVpoC

fn main() {
    let v: [i64; 10] = [1..11];
    let diff = sum_square(&v) - square_sum(&v);
    println!("{}", diff);
}

两个函数,每个函数迭代此数组。所以我只使用

fn sum_square(v: &[i64; 10]) -> i64 {
    let mut sum: i64 = 0;
    for x in v {
        sum += x * x;
    }
    return sum;
}

似乎有效。 如果我使用第二个函数

// Square sum of the added numbers from 1 to 10 # (1+2+3+...)^2
fn square_sum(v: &[i64; 10]) -> i64{
    let mut sum: i64 = 0;
    for x in v {
    sum += x;
    }
    return sum*sum;
}

我收到一个错误:类型不匹配解决 <core::slice::Iter<'_, i64> as core::iter::Iterator>::Item == i64:

我自己是 Rust 的新手,所以我的解释可能不正确或过时,但看起来问题是由类型不匹配引起的。

fn sum_square(v: &[i64; 10]) -> i64 {
    let mut sum: i64 = 0;
    for x in v {
        sum += x * x;
    }
    return sum;
}

此处 x 的类型为 &i64。它是对数组内部值的引用。在 x 上乘以或应用任何其他运算符会导致它取消引用 - 即 x*x 现在具有类型 i64.

fn square_sum(v: &[i64; 10]) -> i64{
    let mut sum: i64 = 0;
    for x in v {
        sum += x;
    }
    return sum*sum;
}

这里 x 也有类型 &i64,但这次它不会被取消引用。正确的解决方案如下所示:

fn square_sum(v: &[i64; 10]) -> i64{
    let mut sum: i64 = 0;
    for x in v {
        // alternatively sum = x + sum works, but sum = sum + x doesn't.
        sum += *x;
    }
    return sum*sum;
}

Pothead 奶奶有一个合理的解释,但我还想包括一些其他细节。

fn square_sum(v: &[i64]) -> i64 { // 1
    let mut sum = 0;
    for &x in v { // 2
        sum += x;
    }
    sum * sum // 3
}

fn main() {
    let v: Vec<_> = (1..11).collect(); // 4
    let diff = sum_square(&v) - square_sum(&v); //5
    println!("{}", diff);
}
  1. 我们接受数字的切片,而不是对数组的引用。切片只是一大块值以及有多少个值。
  2. 我们绑定到一个引用变量,因此 x 将被隐式取消引用。这意味着不必总是说 *x 来获取变量的值,我们可以使用 x 来获取值。
  3. 不需要明确的 return 声明。当您从方法 return early 时,显式 returns 很有用,但如果函数 returns 是一个值,则函数的最后一条语句是 return 值。
  4. 使用范围并将其 collect 转换为 Veccollect 采用迭代器并生成集合(在本例中为 Vec)。
  5. 我们参考了Vec。 Rust 有 , and &Vec<T> will dereference to &[T].

本着展示更像 Rust 的方法解决这个问题的精神,我还将展示 fold and map:

fn sum_square(v: &[i64]) -> i64 {
    v.iter().map(|i| i * i).fold(0, |accumulator, i| accumulator + i)
}

fn square_sum(v: &[i64]) -> i64 {
    let sum = v.iter().fold(0, |accumulator, &i| accumulator + i);
    sum * sum
}

或使用AdditiveIterator:

use std::iter::AdditiveIterator;

fn sum_square(v: &[i64]) -> i64 {
    v.iter().map(|i| i * i).sum()
}

fn square_sum(v: &[i64]) -> i64 {
    let sum: i64 = v.iter().cloned().sum();
    sum * sum
}