此代码在let c = a;编译错误"使用移动值:a"时按预期失败:
fn main() {
let a: &mut i32 = &mut 0;
let b = a;
let c = a;
}
Run Code Online (Sandbox Code Playgroud)
a被移入b并且不再可用于c的赋值.到现在为止还挺好.
但是,如果我只注释其b类型并将其他所有内容留下:
fn main() {
let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
let c = a;
}
Run Code Online (Sandbox Code Playgroud)
代码再次失败 let c = a;
但这一次有一个非常不同的错误信息:"不能搬出去,a因为它是借来的......借来的*a发生在这里:let b: &mut i32 = a;"
所以,如果我只是注释b的类型:没有a进入b,而是一个"重新"的借用*a?
我错过了什么?
干杯.
为什么编译器拒绝此代码:
struct S<'a> {
i: i32,
r: &'a i32,
}
fn main() {
let mut s = S{i: 0, r: &0};
{
let m1 = &mut s;
m1.r = &m1.i;
}
let m2 = &mut s;
}
Run Code Online (Sandbox Code Playgroud)
错误是:"不能s一次多次借用可变的"(首先借用:m1,第二次借用:) m2.
超出范围s后m1,为什么第一次借用还活着?
我读到了超出原借款人范围的借款范围扩展.然而,这似乎总是涉及原始借款人范围之外的另一个借款人"接管"原始借款,例如,此代码失败并出现完全相同的错误,这对我来说很清楚:
fn main() {
let mut s = 0;
let r: &mut i32;
{
let m1 = &mut s;
r = m1;
}
let m2 = &mut s;
}
Run Code Online (Sandbox Code Playgroud)
在第一个例子中,如果我替换m1.r …
此代码通过编译器(为了澄清生命周期,不会被省略):
struct Foo<'a> {
_field: &'a i32,
}
fn test<'a, 'b, 'c>(_x: &'a mut Foo<'c>, _y: &'b bool) { // case 1
}
fn main() {
let f = &mut Foo { _field: &0 };
{
let p = false;
test(f, &p);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用'b的,而不是'c在test像这样的定义:
fn test<'a, 'b>(_x: &'a mut Foo<'b>, _y: &'b bool) { // case 2
}
Run Code Online (Sandbox Code Playgroud)
代码无法编译("p不能长寿")!
test在案例2 的调用中我期望发生的事情是:
'a设置为实际生命周期f,'b被设置为相交Foo的实际寿命和&p的实际寿命是&p …我正在努力阅读 Barnes 的优秀 Ada 书。这是 11.7 节中链表深度比较的代码示例:
type Cell is
record
Next: access Cell;
Value: Integer;
end record;
function "=" (L, R: access Cell) return Boolean is
begin
if L = null or R = null then -- universal =
return L = R; -- universal = (Line A)
elsif L.Value = R.Value then
return L.Next = R.Next; -- recurses OK (Line B)
else
return False;
end if;
end "=";
Run Code Online (Sandbox Code Playgroud)
我似乎无法理解为什么在 A 行中调用了 Universal_access 类型的运算符“=”(因为偏好规则),但是在 B 行中,调用了用户定义的运算符“=” …