Rust 在指针安全上做了很多功夫。
所有权
在Rust中出现的新概念。
let str1 = String::from("H");
let str2 = str1;
// 编译是不会通过了
println!("{}", str1)
在这里 str1 把它指向地址的所有权给了 str2,str1不再指向任何地址。
可变引用
可变引用有一个很大的限制:在特定作用域中的特定数据有且只有一个可变引用。
这些代码会失败:
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!("{}, {}", r1, r2);
这个限制允许可变性,不过是以一种受限制的方式允许。
新 Rustacean 们经常与此作斗争,因为大部分语言中变量任何时候都是可变的。这个限制的好处是 Rust 可以在编译时就避免数据竞争。
数据竞争(data race)类似于竞态条件,它可由这三个行为造成:
- 两个或更多指针同时访问同一数据。
- 至少有一个指针被用来写入数据。
- 没有同步数据访问的机制。
数据竞争会导致未定义行为,难以在运行时追踪,并且难以诊断和修复;Rust 避免了这种情况的发生,因为它甚至不会编译存在数据竞争的代码!
悬垂引用
让我们尝试创建一个悬垂引用,Rust 会通过一个编译时错误来避免:
fn main() {
let reference_to_nothing = dangle();
}
fn dangle() -> &String {
let s = String::from("hello");
&s
}
dangle Function 尝试返回其内部变量 s 的引用,然而返回之后s 的所被分配的内存因为出栈就会被回收,得到引用的Main Function 引用的也是个未知的内存地址。这非常的危险。
fn no_dangle() -> String {
let s = String::from("hello");
s
}
这样就没问题了,所有权被转移。
Top comments (0)