< 返回版块

leolee0101 发表于 2021-08-07 05:49

Tags:MIR,Vec,borrow

初学者,可能会弄大笑话,希望各位不吝赐教

fn main() {
    let mut x: Vec<i32> = vec!(1i32, 2, 3);

    //更新数组
    //push中对数组进行了可变借用,并在push函数退出时销毁这个借用
    x.push(10);

    {
	    //可变借用1
	let mut y = &mut x;
        y.push(100);

        //可变借用2,注意:此处是对y的借用,不可再对x进行借用,
        //因为y在此时依然存活。
        let z = &mut y;
        z.push(1000);
        //@ error: cannot borrow `*y` as mutable more than once at a time
        //y.push(2000);

	    println!("{:?}", z); //打印: [1, 2, 3, 10, 100, 1000]
    } //y和z在此处被销毁,并释放借用。


	//访问x正常
	println!("{:?}", x); //打印: [1, 2, 3, 10, 100, 1000]
}

x.push(10); x可以直接调用push,可以理解。

而 y 已经 是 x 的 可变借用了,那它调用push 是不是得先解引用。 像这样: (*y).push(100); MIR 中实现,也表明了似乎是这样,只是 是在源码编译到MIR时候自动添加的。

        _9 = &mut (*_7);                 // scope 2 at src/main.rs:14:9: 14:10
        _8 = Vec::<i32>::push(move _9, const 100_i32) -> [return: bb3, unwind: bb12];

同样的,z 作为 y 的可变借用,他调用时,应该两次解引用。 但也可以直接调用。 z.push(1000);

MIR 中实现是:

        _12 = &mut (*(*_10));            // scope 3 at src/main.rs:19:9: 19:10
        _11 = Vec::<i32>::push(move _12, const 1000_i32) -> [return: bb4, unwind: bb12];

评论区

写评论
作者 leolee0101 2021-08-07 12:17

感谢。之前以为会严格类型检查,会要求类型完全匹配才能调用。

--
👇
gwy15: https://doc.rust-lang.org/reference/expressions/method-call-expr.html

作者 leolee0101 2021-08-07 12:11

感谢,看起来是这样。

--
👇
lineCode: 自动解引用吧

zg9uagfv 2021-08-07 10:55

直接看成指针操作就可以

gwy15 2021-08-07 10:55

https://doc.rust-lang.org/reference/expressions/method-call-expr.html

lineCode 2021-08-07 08:07

自动解引用吧

1 共 5 条评论, 1 页