MOXUY

Jul 04, 2022

rust记忆点2

所有权

所有权规则

  • Rust中的每一个值都有一个被称为其所有者的变量
  • 值在任一时刻有且只有一个所有者。
  • 当所有者(变量)离开作用域,这个值将被丢弃。

String类型

在 Rust 中声明string类型的变量需要这样操作

1
let s = String::from("hello"); // 声明

虽然string类型的数据都是被存放在堆中,但是复制string类型的变量和 JavaScript 不同,如果简单的赋值

1
2
let s1 = String::from("hello"); // 声明
let s2 = s1; // rust中称之为移动而不是复制

那么s1就会自动被垃圾回收机制回收,因为s1s2在栈中指向的是堆中同一个地址,所以如果s1s2离开作用域,他们都会尝试释放相同的内存,这就会导致二次释放的错误,会导致内存污染和潜在的安全漏洞。

如果一定要复制,则可使用clone

1
2
let s1 = String::from("hello"); // 声明
let s2 = s1.clone();

引用和借用

只传递值而不传递所有权可以使用引用,比如

1
2
3
4
5
6
7
8
9
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1); // 在变量前加一个&符号即表示引用,它们允许你使用值但不获取其所有权
println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
s.len()
}

将创建一个引用的行为称为 借用(borrowing),函数使用引用的变量不可修改变量的值。

可变引用

允许函数修改变量的值
注意:在同一时间只能有一个对某一特定数据的可变引用,避免数据竞争
不能在拥有不可变引用的同时拥有可变引用

数据竞争由这三个行为造成:

  • 两个或更多指针同时访问同一数据。
  • 至少有一个指针被用来写入数据。
  • 没有同步数据访问的机制。

在声明变量前添加 mut 即可,参数的位置也需要添加

1
2
3
4
5
6
7
8
9
fn main() {
let mut s = String::from("hello");

change(&mut s);
}

fn change(some_string: &mut String) {
some_string.push_str(", world");
}

悬垂引用

引用的规则

所有权与函数的示例

tags: 笔记 Rust
OLDER > < NEWER