< 返回版块

zydxhs 发表于 2020-06-16 23:22

Tags:rust

如下代码,fill_vec 的参数为 mut vec: Vec<i32> 可以正常运行;如果参数改为 vec: &mut Vec<i32> 怎么写函数 fill_vec 呢?

我知道的一个写法:fn fill_vec(vec: &mut Vec<i32>) { ... }

mut 在函数参数中不同的位置,有什么区别呢,适用于什么应用场景呢?

fn main() {
    let vec0 = Vec::new();

    let mut vec1 = fill_vec(vec0);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

    vec1.push(88);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}

fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
    vec.push(22);
    vec.push(44);
    vec.push(66);

    vec
}

fn fill_vec2(vec: &mut Vec<i32>) {
    vec.push(1);
    vec.push(2);
}

评论区

写评论
作者 zydxhs 2020-06-18 22:12

这样写也是可以的:

fn f3(mut vec: &mut Vec<i32>) {
    vec.push(42);

    // let leaded_vec = std::boxed::Box::leak(Box::new(vec![1024]));
    let leaded_vec = vec![1111i32, 2222];
    *vec = leaded_vec;
    vec.push(2048);
    dbg!(vec);
}
作者 zydxhs 2020-06-18 20:26

@whfuyn 你的代码存在如下问题:

  1. 代码编译失败
vec = leaked_vec; // 修改vec

应改为:

*vec = leaded_vec.to_vec();
  1. main 中的输出不正确,应该是 1024 2048

对以下内容的回复:

Mike Tang 2020-06-17 00:27

写在后面是参数变量类型的一部分,可变借用,表示可修改所绑定的的资源内容,写在前面指示参数变量本身绑定可变化,跟普通变量一样的。

另外如果是绑定拥有所有权的话,mut在前面有两层意思:

  1. 绑定本身可变
  2. 此绑定可修改资源中的内容。
whfuyn 2020-06-17 00:12

语义不一样。

fn f(mut vec: Vec<i32>)vec的类型是 Vec<i32>f(vec)的调用是会把vec给move掉的,f会拿到vec的所有权,前面的mut是指在f这个函数里,vec是可变的,和let mut vec = vec![]意思差不多。

fn f(vec: &mut Vec<i32>)vec的类型是 &mut Vec<32>,是个可变借用,不会拿走所有权。

作为对比,你可以再考虑一下两个位置都有mut的情况:


fn f(mut vec: &mut Vec<i32>){
    vec.push(42);
    // 此处使用leak是为了满足生命周期要求
    let leaked_vec = std::boxed::Box::leak(Box::new(vec![1024]));
    vec = leaked_vec; // 修改vec
    vec.push(2048);
    dbg!(vec); // 1024 2048
}

fn main() {
    let mut main_vec = vec![];
    f(&mut main_vec);
    dbg!(main_vec); // 42
}
1 共 4 条评论, 1 页