如何按元素添加两个 Rust 数组?

5 arrays rust

这是一个绝对的初学者问题,但在搜索半小时后我找不到任何有用的东西。我有 Rust 1.7.0 和这个代码:

type coord = [i64; 3];

// add two coordinates ("vectors") pointwise, that is
// if z = add(a, b) then z[i] = a[i] + b[i] for i=0..2
fn add(a: coord, b: coord) -> coord {
    //???
}
Run Code Online (Sandbox Code Playgroud)

我首先尝试的显而易见的事情是a.zip(b).map(|(u,v)| u+v)但这不起作用(不能压缩数组),也不能a.iter().zip(b.iter()).map(|(u,v)| u+v)因为它无法将迭代器转换回数组。我可以理解为什么这通常不起作用,但在这种情况下,我们知道两者的长度相同。

现在我正在做

fn add(a: coord, b: coord) -> coord {
    let mut z: coord = [0, 0, 0];
    for i in 0..2 {
        z[i] = a[i] + b[i];
    }
    z
}
Run Code Online (Sandbox Code Playgroud)

但相比之下,它看起来很丑。我错过了什么?

use*_*342 6

一种简单的方法是使用enumerate迭代器方法生成索引并z通过分配到获得的索引来填充“明显”方式:

type Coord = [i64; 3];

fn add(a: Coord, b: Coord) -> Coord {
    let mut z: Coord = [0, 0, 0];
    for (i, (aval, bval)) in a.iter().zip(&b).enumerate() {
        z[i] = aval + bval;
    }
    z
}

fn main() {
    let x: Coord = [1, 2, 3];
    let y: Coord = [1, 1, 1];
    assert!(add(x, y) == [2, 3, 4]);
}
Run Code Online (Sandbox Code Playgroud)

在 Rust 中,我们可以做得更好,注意它iter()会生成对数组的引用iter_mut(),并且可用于生成可变引用。这会产生与您尝试编写的代码非常相似的代码:

fn add(a: Coord, b: Coord) -> Coord {
    let mut z: Coord = [0, 0, 0];
    for ((zref, aval), bval) in z.iter_mut().zip(&a).zip(&b) {
        *zval = aval + bval;
    }
    z
}
Run Code Online (Sandbox Code Playgroud)

如果这种写入模式z在不同的操作中重复出现,您可以抽象 new 的创建Coord并将其填充到通用函数中:

fn new_coord_from<F: Iterator<Item=i64>>(src: F) -> Coord {
    let mut result = [0; 3];
    for (rref, val) in result.iter_mut().zip(src) {
        *rref = val;
    }
    result
}
Run Code Online (Sandbox Code Playgroud)

add然后看起来就像我们想要的那样:

fn add(a: Coord, b: Coord) -> Coord {
    new_coord_from(a.iter().zip(&b).map(|(a, b)| a + b))
}
Run Code Online (Sandbox Code Playgroud)