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

时间:2015-02-27 23:50:06

标签: arrays loops rust

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

代码(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);
}

我在主函数中有一个数组,填充1-10的数字(是的,我知道[1..11]不起作用,但是什么是最好的解决方案?使用“范围”是不可能的,我想要一个数组,而不必键入每个数字)。 现在我需要在不同的函数中多次迭代这个数组(这里是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

2 个答案:

答案 0 :(得分:2)

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声明。当您从方法返回 early 时,显式返回很有用,但如果函数返回一个值,那么函数的最后一个语句就是返回值。
  4. 使用范围并collect将其放入Veccollect使用迭代器并创建一个集合(在本例中为Vec)。
  5. 我们引用了Vec。 Rust有auto-dereferencing rules&Vec<T> will dereference to &[T]
  6. 本着展示解决此问题的更类似Rust的方式的精神,我还将展示foldmap

    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
    }
    

答案 1 :(得分:1)

我自己也是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;
}