当我想知道可变引用如何转移到方法中时,所有问题都开始了。
let a = &mut x;
a.somemethod(); // value of a should have moved
a.anothermethod(); // but it works.
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索了很多。(真的很多)而且我注意到作为参数传递给函数的可变引用总是会经历以下转换。(这称为再借)
fn test(&mut a) -> ();
let a = &mut x;
test(a); // what we write in code.
test(&mut *a); // the actual action in code.
Run Code Online (Sandbox Code Playgroud)
因此,我在谷歌上搜索了更多有关“再借”的详细信息。
这就是我所拥有的。
在任何代码中,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; // …Run Code Online (Sandbox Code Playgroud) https://cs3110.github.io/textbook/chapters/data/type_synonym.html
正如我们在上面看到的,
type a = int * int * int
Run Code Online (Sandbox Code Playgroud)
type a是 的同义词int * int * int。
因此,如果我们声明int * int * int多个名称,它们都是相同的类型。
type a = int * int * int
type b = int * int * int
type c = int * int * int
Run Code Online (Sandbox Code Playgroud)
a和b和c是相同类型。
他们没有数据构造函数。确实,不需要,也不应该,因为它们只是同义词。
然而,当我们查看记录时,情况却截然不同。
type a = { name : string }
type b = { name : string }
type c = { name …Run Code Online (Sandbox Code Playgroud) 我已经认识到,当移动取消引用Box的时*Box::new(_),它不会调用Deref::deref或DerefMut::deref_mut;它确实移动了值,这意味着*Box::new(_)拥有所有权,而不是对引用的取消引用。
一个例子:
let a = Box::new(String::from("hello");
let b = *a;
Run Code Online (Sandbox Code Playgroud)
我了解到这Box是一个非凡的结构,因此在数据移动的情况下,它实际上像引用一样取消引用(没有Deref特征)。
Box移动过程中,堆中分配的内存发生了什么变化?它被释放了吗?是用一堆零代替的吗?是否仍然没有任何访问方式?
我知道分配的内存在删除String::from时将被释放b。我对数据并不好奇str type hello,我对大小为 的内存感到好奇size of String。
我如何显式取消引用Box没有Deref特征的?当我尝试时,它会Box通过调用自动借用Deref::deref。
let a = Box::new(String::from("hello"));
fn test(i: &String) {}
test(&(*a));
Run Code Online (Sandbox Code Playgroud)
编译器推断不需要 move *a,因此看起来它是通过特征取消引用,而不是直接取消引用。
本例成功消耗了盒子和字符串:
let a = Box::new(String::from("hello"));
fn test(i: &String) {}
test(&(*a));
Run Code Online (Sandbox Code Playgroud)
rust ×2
box ×1
constructor ×1
dereference ×1
lifetime ×1
memory-leaks ×1
ocaml ×1
record ×1
reference ×1