所有权
Rust 的内存管理模型
- Rust 中每个值都绑定有一个变量,称为该值的所有者
- 每个值只有一个所有者,而且每个值都有它的作用域
- Rust中,
{}
就是作用域 - 所有权被转交后,就不能用原来的变量访问
- Rust中,
- 一旦当这个值离开作用域,这个值占用的内存将被回收
借用
- 希望使用一个值而不是拥有这个值(在函数调用时特别常见) ```rust // 报错的代码 fn echo(s: String) { println!(“{}”, s); } fn main() { let s = String::from(“Hello”); echo(s); println!(“{}”, s); // 报错:value borrowed here after move }
// 使用借用改良 fn echo(s: &String) { println!(“{}”, s); } fn main() { let s = String::from(“Hello”); echo(&s); println!(“{}”, s); }
<a name="ShBLj"></a>
# 不可变引用和可变引用
- 默认情况,引用不可变
- 需要修改引用的值,使用`&mut`
```rust
fn echo(s: &String) {
println!("{}", s);
}
fn change(s: &mut String) {
s.push_str(" changed");
}
fn main() {
let mut s = String::from("Hello");
echo(&s);
change(&mut s);
echo(&s);
}
可变引用的规则
- 同一时间最多只能存在一个可变引用
此规则主要用于防止数据竞争
fn main() {
let mut s = String::from("Hello");
let s1_ref = &mut s;
let s2_ref = &mut s1_ref; // cannot borrow as mutable
println!("{}", s2_ref);
}
生命周期
绝大多数情况,Rust编译器可以自动推导每个变量的生命周期
-
生命周期注解
语法:生命周期参数名称必须以撇号
'
开头- 其名称通常为全小写,类似于泛型,其名称非常短
'a
是大多数人默认使用的名称- 生命周期参数注解位于引用的&之后,并有一个空格来将引用类型与生命周期分隔开
- 生命周期注解并不改变任何引用的生命周期长短
```rust
// 不加生命周期会报错: expected named lifetime parameter
// 因为 -> str 可以是 str1/str2,两者可能有不同生命周期
fn bigger<’a>(str1: &’a str, str2: &’a str) -> &’a str {
if str1 > str2 {
} else {str1
} }str2
fn main() { println!(“{}”, bigger(“a”, “b”)); }
```rust
#[derive(Debug)]
struct Person<'a> {
name: &'a str,
}
fn main() {
let p = Person { name: "mike" };
println!("{:?}", p);
}