通过消耗两个向量来创建新向量的好方法是什么?

时间:2015-08-19 04:16:08

标签: vector rust

我想要一个很好的函数来创建一个新的向量,并传达参数向量不再相关并且应该被销毁,取得它们的所有权。我并不特别希望让任何一个参数变为可变(使用appendextendpush_all,从而更改调用签名)。代码(playpen link):

fn main () {
    let arg1 = vec![1, 2, 3];
    let arg2 = vec![4, 5, 6];
    let desired = consume_and_concat(arg1, arg2);
    assert_eq!(desired, vec![1, 2, 3, 4, 5, 6]);
}

fn consume_and_concat(vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> {
    // something nice here
}

我知道+没有Vec。在Ruby中,我会vec1 + vec2vec1.concat(vec2)[vec1, vec2].flatten。是否有类似优雅的东西,我错过了?

3 个答案:

答案 0 :(得分:8)

我认为您正在寻找Extend::extend

fn main() {
    let mut arg1 = vec![1, 2, 3];
    let arg2 = vec![4, 5, 6];
    arg1.extend(arg2);
    assert_eq!(arg1, vec![1, 2, 3, 4, 5, 6]);
}

在这里,我们可以重用arg1中分配的空间,但是通过arg2分配的空间无法有效完成任务。有关您原始问题更具体的示例:

fn main() {
    let arg1 = vec![1, 2, 3];
    let arg2 = vec![4, 5, 6];
    let desired = consume_and_concat(arg1, arg2);
    assert_eq!(desired, vec![1, 2, 3, 4, 5, 6]);
}

fn consume_and_concat(mut vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> {
    vec1.extend(vec2);
    vec1
}

答案 1 :(得分:4)

我想指出,在签名中标记参数mut是不必要的;这只是一条捷径。

因此,我们可以在不修改签名的情况下实现所需的结果:

fn consume_and_concat(vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> {
    let mut vec1 = vec1;
    vec1.extend(vec2);
    vec1
}

因为我们重用了vec1内部缓冲区,所以它几乎和它一样高效(为了提高效率,检查 {/ 1>}和vec1的容量可能会带来更好的结果。)

当然,快捷方式:

vec2

是,更短,并且正如您已经意识到的那样,fn consume_and_concat(mut vec1: Vec<i32>, vec2: Vec<i32>) -> Vec<i32> { vec1.extend(vec2); vec1 } vec1的事实不会改变其参数的类型,因此不会更改传递参数的方式。

答案 2 :(得分:1)

你不需要它们中的任何一个是可变的,不过如果有一个你会在重新分配上节省一点。有了Rust,其中一件好事就是你不必说它会消耗掉它。你可以从函数签名中分辨出来。由于它没有引用,这意味着该功能正在取得所有权。

if (!empty($album)){
    foreach ($album as $key => $value){
        echo $value;
    } 
}else {
    echo '0 found';
}