我在找一门语言学习,我发现Rust越来越流行.
关于Rust 、内存安全和防止故障,有两件事给我留下了深刻印象.
rust 是如何做到这一点的?例如,Rust和Java之间有什么区别可以实现Rust的安全功能?
我在找一门语言学习,我发现Rust越来越流行.
关于Rust 、内存安全和防止故障,有两件事给我留下了深刻印象.
rust 是如何做到这一点的?例如,Rust和Java之间有什么区别可以实现Rust的安全功能?
Rust实现内存安全的核心其实很简单.它主要取决于两个原则:所有权和借款.
Ownership
编译器使用仿射类型系统跟踪每个值的所有权:一个值最多只能使用一次,之后编译器拒绝再次使用它.
fn main() {
let original = "Hello, World!".to_string();
let other = original;
println!("{}", original);
}
产生一个错误:
error[E0382]: use of moved value: `original`
--> src/main.rs:4:20
|
3 | let other = original;
| ----- value moved here
4 | println!("{}", original);
| ^^^^^^^^ value used here after move
|
= note: move occurs because `original` has type `std::string::String`, which does not implement the `Copy` trait
特别是,防止了C或C++中经常遇到的可怕的double-free(在智能指针之前).
Borrowing
rust 病带来的启示是,当混淆了别名和易变性时,就会出现内存问题:也就是说,当一块内存可以通过多条路径访问时,它会发生变异(或移动),留下dangling pointers个.
因此,借阅判断的核心原则是:Mutability XOR Aliasing.原则上,它类似于读写锁.
这意味着Rust编译器跟踪aliasing条信息,它使用lifetime annotations(&'a var
中的'a
条)将引用的生存期和它们引用的值连接在一起.
如果有人引用某个值或将其放入其中(例如,引用struct
的字段或集合的元素),则会borrow 该值.借来的价值不能移动.
Mutability (without aliasing)
在任何时候,你只能获得一个mutable reference(&mut T
)到一个给定的值,并且这个值可能不存在immutable reference到同一时间;它保证你可以独占地访问这一小块内存,因此你可以安全地对它进行变异.
Aliasing (without mutability)
您可以随时将多个immutable references(&T
)转换为给定值.但是,您不能通过这些引用(*)来改变任何内容.
(*) I am lying; there are structs like 100 which implement "interior mutability"; they do respect the Mutability XOR Aliasing principle, but defer the check to run-time instead.
That's it?
差不多如此;)
对于编译器编写者来说,它的实现已经相当复杂,并且可能会过度约束用户(使用该系统无法证明某些安全的程序是安全的,需要跳转),然而核心原则实际上就这么简单.
So what's left?
边界判断.这不是火箭科学,但可能会导致性能下降.大多数语言都有一定程度的支持,C是一个大的例外,C++有some的支持,虽然它是可选的.