我正在寻找一种学习语言,我看到Rust变得非常受欢迎。
有两件事让我印象深刻的是Rust,内存安全和防止段错误。
Rust如何实现这一目标?例如,Rust和Java之间有什么区别可以实现Rust的安全功能?
答案 0 :(得分:19)
Rust如何实现内存安全,其核心实际上非常简单。它主要取决于两个原则:所有权和借款。
<强>所有权强>
编译器使用仿射类型系统来跟踪每个值的所有权:一个值最多只能使用一次,之后编译器拒绝再次使用它。
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 ++中经常遇到的可怕的双重(在智能指针之前)。
<强>借款强>
来自Rust的照明是当混合别名和可变性时发生内存问题:也就是说,当一个内存可以通过多个路径访问并且它被突变(或移开)而留下悬空指针
借用检查的核心原则是:可变性XOR别名。原则上它类似于读写锁。
这意味着Rust编译器跟踪别名信息,为此它使用生命周期注释('a
中的那些&'a var
)来连接引用的生命周期和它们一起引用的值。
如果某人有引用它或INTO它(例如,对struct
的字段或对集合的元素的引用),则借用该值。借来的价值无法移动。
可变性(没有别名)
您可以随时在给定值中只获取一个可变引用(&mut T
),并且此值中不存在不可变引用同一时间;它保证您可以独占访问这些内存,因此您可以安全地改变它。
别名(没有可变性)
您可以随时将多个不可变引用(&T
)添加到给定值中。但是,你不能通过这些引用(*)来改变任何东西。
(*)我撒谎;像RefCell
这样的结构实现了“内部可变性”;他们确实尊重Mutability XOR Aliasing原则,但将检查推迟到运行时。
就是这样?
差不多;)
为编译器编写器实现它已经相当复杂,并且可能会过度约束用户(某些安全的程序无法通过此系统证明是安全的,需要跳过箍),但核心原则确实如此就这么简单。
那剩下什么了?
边界检查。这不是火箭科学,但可能会导致性能损失。大多数语言都有一定程度的支持,C是一个很大的例外,C ++有一些支持它,虽然它是可选的。