如何在元素上添加两个Rust数组? [英] How do I add two Rust arrays element-wise?

查看:88
本文介绍了如何在元素上添加两个Rust数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is an absolute beginner question, but I can't find anything useful after searching for half an hour. I have Rust 1.7.0 and this code:

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 {
    //???
}

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

The obvious thing I tried first is a.zip(b).map(|(u,v)| u+v) but this doesn't work (can't zip arrays), nor does a.iter().zip(b.iter()).map(|(u,v)| u+v) because it can't convert the iterator back to an array. I can see why this doesn't work in general but in this case we know both things are the same length.

现在我正在做

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
}

但相比之下,它看起来很难看。我缺少什么?

but it looks ugly by comparison. What am I missing?

推荐答案

一种简单的方法是使用枚举迭代器方法,并通过分配获得的索引来填充 z 显而易见的方式:

One simple approach is to generate indices using the enumerate iterator method and fill z the "obvious" way, by assigning into the obtained indices:

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]);
}

在Rust中,通过注意到 iter()在数组中生成引用,并且 iter_mut()可用于生成可变引用。这样产生的代码与您尝试编写的代码非常相似:

In Rust, we can do better than that by noticing that iter() produces references into the array, and iter_mut() is available to produce mutable references. This results in code very similar to what you attempted to write:

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
}

如果这种写入方式 z 重复执行不同的操作,您可以抽象创建新的 Coord 并将其填充到通用函数中的数据:

If this pattern of writing into z recurs with different operations, you can abstract the creation of new Coord and filling it with data into a generic function:

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
}

添加,然后看起来就像我们想要的那样:

add then looks just like we'd like it to:

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

这篇关于如何在元素上添加两个Rust数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆