2020/07/05
事件一:理解所有权ownership
核心内容:
1、All data stored on the stack must have a known, fixed size. Data with an unknown size at compile time or a size that might change must be stored on the heap instead.
2、很有意思的一段代码:
let s1 = String::from("I love you");
let s2 = s1;
println!("{} and {}",s1,s2);
String类型的具体data存储在堆上,如果s2完全复制s1的data,那么耗时耗力;如果s2和s1的ptr部分同时指向同一内存区域,那么根据作用域的规则,如果s1和s2先后离开自身的作用域,会对同一个内存空间进行两次free,造成内存泄漏。因此,这里执行的结果是把s1绑定数值的所有权转交给s2,而s1失去对原data的所有权。
解决方法:
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {}, s2 = {}", s1, s2);
这样s2就是一个对s1的深度复制,不指向同一个内存空间。
let s1 = String::from("hello");
let s2 = &s1;
println!("s1 = {}, s2 = {}", s1, s2);
这里s2是对s1的借用,借用期间,s1不能再次被借用。
3、关于&str的理解。
&str的本质是一个胖指针,指向字面量。字面量是直接写死在代码中的,存储在内存中对应位置。&str本身存储在栈中。
let mut s = "I love you";
s= "You love me";
println!("{}",s);
“I love you”和“You love me”都是随着代码写死在数据段中的,s为可变的指针。调用赋值语句的时候其实是让s指向另一个位置的字符串。
4、函数调用所有权转移与赋值语句是基本一致的(堆上数据move,栈上数据copy)
5、可修改的全局变量
static mut s:i32 = 0;
使用的时候需要使用
unsafe
{
}