如何在应用的操作中创建通用的Rust函数?

时间:2016-10-25 13:32:28

标签: rust

我有一个名为new_vec的函数。通过对压缩矢量中的元素对执行元素运算,它需要两个向量并创建一个新向量。

fn main() {
    let v1s = vec![1, 0, 1];
    let v2s = vec![0, 1, 1];
    let v3s = new_vec(v1s, v2s);
    println!("{:?}", v3s) // [1, 1, 2]
}

fn new_vec(v1s: Vec<i32>, v2s: Vec<i32>) -> Vec<i32> {
    let mut v3s = Vec::<i32>::new();
    for (v1, v2) in v1s.iter().zip(v2s.iter()) {
         v3s.push(v1 + v2) // would also like to use -
    }
    v3s
}

我希望有一个new_vec函数用于可以在两个整数上使用的公共二元操作,例如+-/,{{ 1}}。

我该怎么做?我可以想象两种方式:宏和闭包。如何以最佳方式执行此操作的最小示例,例如*+,我们将不胜感激。

1 个答案:

答案 0 :(得分:5)

我会通过一个关闭:

fn new_vec<F>(v1s: &[i32], v2s: &[i32], foo: F) -> Vec<i32>
    where F: Fn(i32, i32) -> i32
{
    let mut v3s = Vec::<i32>::new();
    for (&v1, &v2) in v1s.iter().zip(v2s.iter()) {
        v3s.push(foo(v1, v2))
    }
    v3s
}

fn main() {
    let v1s = vec![1, 0, 1];
    let v2s = vec![0, 1, 1];
    let v3s = new_vec(&v1s, &v2s, |x, y| x - y);
    let v4s = new_vec(&v1s, &v2s, |x, y| x + y);
    println!("{:?}", v3s); // [1, -1, 0]
    println!("{:?}", v4s); // [1, 1, 2]
}

注意前两个参数的变化;如果你的函数不需要使用它的参数,references are preferable to Vectors - 在这种情况下是&[i32]

此实现效率不高,因为生成的Vec tor会逐渐扩展;如果您按如下方式修改它以减少分配数量会更好:

fn new_vec<F>(v1s: &[i32], v2s: &[i32], foo: F) -> Vec<i32>
    where F: Fn(i32, i32) -> i32
{
    v1s.iter().zip(v2s.iter()).map(|(&x, &y)| foo(x, y)).collect()
}