我想要一个很好的函数来创建一个新的向量,并传达参数向量不再相关并且应该被销毁,取得它们的所有权。我并不特别希望让任何一个参数变为可变(使用append
,extend
或push_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 + vec2
或vec1.concat(vec2)
或[vec1, vec2].flatten
。是否有类似优雅的东西,我错过了?
答案 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';
}