..
Rust 学习笔记(1)
学习Rust的第一天,关于内存管理和所有权。
栈和堆 Stack and Heap
数据分配在栈或者堆上。
- 栈占用连续的内存,是一种先进后出的数据结构,储存在栈上的数据要求必须是已知且固定大小。
- 堆不要求连续的内存,可以存放可变长度的数据。
数据保存到栈上比保存到堆上更高效,保存到栈上可以直接在栈顶操作,对比保存到堆上涉及到更多的操作:
- 内存分配器寻找合适的内存位置
- 标记该内存位置已占用
访问栈上的数据比访问在堆上的更高效,栈的内存是连续的,处理器可以非常快速的访问这样的内存,对比堆上的数据是不连续的,而且,访问堆上的数据必须通过保存了内存地址的指针访问,涉及更多的操作。
内存管理 Memory Management
内存管理通常是指管理由内存分配器分配给堆使用的内存。常用的由三种方法:
- Java,Go等语言用垃圾回收 GC
- C,C++等语言需要手动分配及释放
- Rust 用所有权机制
作用域 Scope
在 Rust 中,作用域是指由 { ... }
组成一段代码片段。如果变量在某个作用域中定义,那么在作用域以外,这个变量将无法访问。
{ // s is not valid here, it’s not yet declared
let s = "hello"; // s is valid from this point forward
// do stuff with s
} // this scope is now over, and s is no longer valid
所有权 Ownership
所有权规则:
- 指向值的变量作为所有人。
- 同一时间只能有一个所有人。
- 当变量出作用域时,对应的值将被自动释放。
释放
{
let s = String::from("hello"); // s 的值保存在堆上
// do stuff with s
} // 作用域结束,s 被自动释放
转移
String
的内存布局如下图所示:
当s1赋值给s2的时候,s1和s2同时指向同一个值:
当s1和s2作用域结束时,根据所有权规则,s1和s2对应的值都会被释放。但同一段内存释放两次会出错,为了保证内存安全,Rust 在s1赋值给s2的时候会将所有权转移给s2:
同时s1将无法访问:
let s1 = String::from("hello");
let s2 = s1; // s1 对应的值所有权转移到了 s2,s1 后面将无法访问
println!("{}", s1);
参考资料
- https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html