Rust 如何理解锈病的危害和所有权?
这是一个错误:Rust 如何理解锈病的危害和所有权?,rust,Rust,这是一个错误: struct A(i32); fn main(){ let a = A(1); let ra = &a; let x = *ra; } 但这是可以的(仅将&更改为Box::new): 这里发生了什么事 当我将其添加到(1)时: 上面写着“移动值的使用:ra”。但我只是移动了*ra。 如果在第二段代码中它移动ra,那么在第一段代码中为什么它不移动ra 我写我的框(通过Rust编程语言15.2),但它也不能移动ra,并报告错误: use std::
struct A(i32);
fn main(){
let a = A(1);
let ra = &a;
let x = *ra;
}
但这是可以的(仅将&
更改为Box::new
):
这里发生了什么事
当我将其添加到(1)时:
上面写着“移动值的使用:ra
”。但我只是移动了*ra
。
如果在第二段代码中它移动ra,那么在第一段代码中为什么它不移动ra
我写我的框(通过Rust编程语言15.2),但它也不能移动ra,并报告错误:
use std::ops::Deref;
struct A(i32);
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> {
MyBox(x)
}
}
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
fn main(){
let a = A(1);
let ra = MyBox::new(a);
let x = *ra;
}
使用std::ops::Deref;
结构A(i32);
结构MyBox(T);
impl MyBox{
fn新(x:T)->MyBox{
MyBox(x)
}
}
为MyBox执行命令{
类型目标=T;
fn-deref(&self)->&T{
&self.0
}
}
fn main(){
设a=a(1);
设ra=MyBox::new(a);
设x=*ra;
}
在您的第一个示例中,发生了什么:
struct A(i32);
fn main(){
let a = A(1); // A(1) is in `a` variable
let ra = &a; // `ra` references to `a`.
println!("{}", a.0); // `a` itself is still exists here and you can read it
let x = *ra; // A(1) is being tried to be moved from `a`. Error here
let x = a; // but you can move value from `a` directly. It's ok here.
// `a` does not exist any more
// println!("{}", a.0); // error here
}
在行中,设x=*ra代码>您正试图从引用后面“提取”值。但是ra
不拥有该值。它归a
所有。所以,若变量不拥有值,则不能从变量中移动值
在你的第二个例子中,发生了不同的事情
struct A(i32);
fn main(){
let a = A(1); // A(1) is in `a`
let ra = Box::new(a); // value `A(1)` is moved from `a` to boxed.
// you can't access to `a` now:
// println!("{}", a.0); // error here
let x = *ra; // here you are trying to move value from the memory location where `Box` points to.
// `ra` does not exist any more!
// println!("{}", ra.0); // error here. Used of moved value
}
Box
拥有A(1)
。只要没有对A(1)
的引用,您就可以将值移到框的后面
如果要尝试获取对框后面的值的引用,则也不能通过取消引用来移动:
struct A(i32);
fn main(){
let a = A(1); // A(1) is in `a`
let ra = Box::new(a); // value `A(1)` is moved from `a` to box.
let ra_ref = &ra;
// both `ra_ref` and `ra` are accesseble here
// let x = *ra; // here you are trying to move value from the memory location where `Box` points to. Error as long as there `ra_ref`
println!("{}", ra_ref.0);
}
添加ra2
行后,两个代码段中都存在借用检查器错误。是什么让你认为它们中的一个有效呢?Box
是特别的。请参阅并详细说明@trentcl的评论:框
被认为是一种内置引用/指针类型,与&T
和&mut
一样多。这几乎无关紧要,但这是罕见的案例之一。解引用操作符为内置引用/指针创建一个“位置表达式”,但对于其他所有对象(包括“智能指针”,如MyBox
),它充当*Deref::Deref(&ra)
),因此在本例中*&ra.0
,因此出现错误。如果这似乎没有意义,那是因为它没有真正意义。这只是一种生锈的怪癖。@Coder-256*Deref::Deref(&ra)
仍然是一个位置表达式,只是一个无法移出的表达式&T
和&mut T
也很特别,因为它们不必经过Deref
和DerefMut
,但是框可以通过*
以破坏性方式移出,这一事实基本上是正交的,是什么使它特别的/吹毛求疵
struct A(i32);
fn main(){
let a = A(1); // A(1) is in `a`
let ra = Box::new(a); // value `A(1)` is moved from `a` to boxed.
// you can't access to `a` now:
// println!("{}", a.0); // error here
let x = *ra; // here you are trying to move value from the memory location where `Box` points to.
// `ra` does not exist any more!
// println!("{}", ra.0); // error here. Used of moved value
}
struct A(i32);
fn main(){
let a = A(1); // A(1) is in `a`
let ra = Box::new(a); // value `A(1)` is moved from `a` to box.
let ra_ref = &ra;
// both `ra_ref` and `ra` are accesseble here
// let x = *ra; // here you are trying to move value from the memory location where `Box` points to. Error as long as there `ra_ref`
println!("{}", ra_ref.0);
}