如果我借用一个解除引用的指针会怎么样?
let a = some object;
let b = &a;
let c = &*b;
借用了什么对象?解除引用操作是否会创建一个临时对象,如函数的返回值?它如何遵守借用规则。
我也对Box的可变语义感到困惑。
let mut a = Box::new(8us)
*a = 1;
这个代码没有Box :: new_mut()这样的代码就可以了。但
let mut a = &8us;
*a = 1;
发生错误。
答案 0 :(得分:0)
快速回答:这取决于。
答案很长:继续阅读...
如果我借用一个解除引用的指针会怎么样? 如果您查看生锈的LLVM-IR,您可以看到所有细节:
let a = 8us;
let b = &a;
let c = &*b;
扩展到
let a;
// %a = alloca i64
let b;
// %b = alloca i64*
let c;
// %c = alloca i64*
a = 8us;
// store i64 8, i64* %a
b = &a;
// store i64* %a, i64** %b
let tmp = *b;
// %0 = load i64** %b
c = tmp;
// store i64* %0, i64** %c
现在,llvm可以很容易地优化这些东西。一旦在自己的类型上实现Deref等特征,它就会变得更加复杂。然后显然涉及函数调用,但很可能再次优化,因为你不应该在deref函数中做复杂的事情。
借用了什么对象?
c
借用a
解除引用操作是否会创建一个临时对象,如函数的返回值?
不,见上文
它如何遵守借用规则。
*b
的行为就像a
一样。如果您参考它,则会引用a
。
回答你的第二个问题:
Box
拥有它指向的对象。由于您声明Box
是可变的,因此可以使用可变引用或任意数量的对象的非可变引用。这意味着当您取消引用Box
生锈时,根据情况决定是否自动创建可变框。在赋值的情况下,你的deref" d框位于赋值运算符的左侧,因此rust会尝试获取对象的可变引用。
如果给出变量类型,这就更明显了:
let mut x = Box::new(8us);
{
let y : &usize = &*x;
}
{
let y : &mut usize = &mut *x;
*x = 99; // cannot assign to `*x` because it is borrowed
}