gpt4 book ai didi

rust - 可变引用的再借用

转载 作者:行者123 更新时间:2023-12-03 11:30:31 26 4
gpt4 key购买 nike

当我想知道可变引用如何进入方法时,所有的问题都开始了。

let a = &mut x;
a.somemethod(); // value of a should have moved
a.anothermethod(); // but it works.
我用谷歌搜索了很多。 (真的很多)
我注意到作为参数传递给函数的可变引用总是经历以下转换。 (这称为再借)
fn test(&mut a) -> ();

let a = &mut x;
test(a); // what we write in code.
test(&mut *a); // the actual action in code.
所以,我在谷歌上搜索了更多关于“再借”的细节。
这就是我所拥有的。
在任何代码中,x 指的是任意数据。我没有提及它,因为我认为它的类型对于讨论并不重要。 (但是,我自己使用了 i32)。
let a = &mut x;
let b = &mut *a; // a isn't available from now on
*a = blahblah; // error! no more access allowed for a
*b = blahblah; // I've wrote this code not to confuse you of the lifetime of b. If not mentioned, it always live till the scope ends.
let a = &mut x;
{
let b = &*a;
// *a = blahblah in this scope will throw an error, just like above case.
}
*a = blahblah; // but this works.
好吧。这很有趣。好像 b不仅借了 x还有 a .
或许,我们可以这样澄清再借: &'a *(&'b mut x) .
借了 x (这里有一个生命周期 'a),
还借了 a (它有一个生命周期'b)。
所以我运行了下面的代码来证实我的猜想。
let x: i32 = 1; // I wanted to make it clear that x lives in this scope.
let b;
{
let a = &mut x;
b = &mut *a;
}
*b = 0;
但这有效!
什么??
但我只是决定得到这个。 &'a mut *&mutx ,不是 &'a mut *&'b mutx .
我不知道为什么 mut x&mut *&mutx 的生命周期内不可用也不为什么 mut x&mut *&mutx 的生命周期后重新可用,但是“好吧,让我们这么说吧”。
但是看看这个。对于清晰和一般的理解,我完全无法理解。
let x: i32 = 1;
let b;
{
let a = &mut x;
let b = &**&a;
} // error!! a should live longer than b!
生命周期不是简单地依赖于真实数据 b指的是??? &'a **& &mut x ,不是 &'a **&'b &'c mut x .
现在呢?? &'a **&'b &mut x ??? (这是我的猜测)。
我该如何接受这种复杂的情况?

最佳答案

这是一些很好的问题!我会尽我所能回答那些我能回答的。
Rust Reference 是寻找此类问题答案的好地方,关于 Rust 的更深层语义。
首先,对于您关于方法解析的问题,the Referencesays :

When looking up a method call, the receiver may be automaticallydereferenced or borrowed in order to call a method. This requires amore complex lookup process than for other functions, since there maybe a number of possible methods to call. The following procedure isused:

The first step is to build a list of candidate receiver types. Obtainthese by repeatedly dereferencing the receiverexpression's type, adding each type encountered to the list, thenfinally attempting an unsized coercion at the end, and adding theresult type if that is successful. Then, for each candidate T, add&T and &mut T to the list immediately after T.

For instance, if the receiver has type Box<[i32;2]>, then thecandidate types will be Box<[i32;2]>, &Box<[i32;2]>, &mut Box<[i32;2]>, [i32; 2] (by dereferencing), &[i32; 2], &mut [i32; 2], [i32] (by unsized coercion), &[i32], and finally &mut [i32].


上面的链接有更详细的介绍。
对于您的其余问题,我认为这主要是关于类型强制。 Some relevant coercions are :
  • &mut T to &T
  • &T or &mut T to &U if T implements Deref<Target = U>
  • &mut T to &mut U if T implements DerefMut<Target = U>

值得注意的是, &U&mut U都实现 Deref<Target = U> , 和 &mut U还实现了 DerefMut<Target = U> .因此,第二/第三条规则导致以下强制:


T是:
胁迫自


&U &&U &U &U &mut &U &U &mut U &&mut U &U &mut U &mut &mut U &mut U

现在有了引用资料,让我们更详细地看看您的问题:
let a = &mut x;
let b = &mut *a; // a isn't available from now on
*a = blahblah; // error! no more access allowed for a
*b = blahblah; // I've wrote this code not to confuse you of the lifetime of b. If not mentioned, it always live till the scope ends.

为了写入引用,它显然必须是可变(也称为唯一)引用。当你写 let a = &mut x , 现在 a是访问 x 的唯一途径.现在当你写 let b = &mut *a ,它本质上意味着 let b = &mut *(&mut x) ,简化为 let b = &mut x .
在这里, b可变借用 a , Rust 不会让你使用 a直到 b被摧毁了……或者现在看起来是这样。
let a = &mut x;
{
let b = &*a;
// *a = blahblah in this scope will throw an error, just like above case.
}
*a = blahblah; // but this works.

在这里, let b = &*a变成 let b = &*(&mut x) ,所以 let b = &x .无论何种引用 b是, a是一个可变引用并且必须是唯一的,所以在 b 之前你不能使用它消失了(超出范围)。
let mut x: i32 = 1; // I wanted to make it clear that x lives in this scope.
let b;
{
let a = &mut x;
b = &mut *a;
}
*b = 0;

(我假设你的意思是 let mut x )。
现在这就是它变得有趣的地方。在这里,由于 ab两者都可变地指向同一个对象,Rust 不会让你使用 a直到 b被摧毁。似乎推理应该是,“因为 b 可变地借用了 a”,但实际上并非如此。通常, b实际上会借 a ,这就是像 Box 这样的智能指针的情况。 , std::cell::RefMut等。然而,引用得到特殊处理:Rust 可以分析它们指向的内存。
所以当你写 let b = &mut *a , b实际上并没有借 a !它只借用数据 a指着。这种区别以前不相关,但在这里它允许代码编译。
至于你的最后一个例子,我无法按照你描述的方式打破它。

关于rust - 可变引用的再借用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65474162/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com