我在找一门语言学习,我发现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的支持,虽然它是可选的.

Rust相关问答推荐

为什么我需要在这个代码示例中使用&

rust 迹-内存管理-POP所有权-链表

在Rust中,在实现特征`Display`时,如何获取调用方指定的格式?

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

如何使用RefCell::JOYMOMTborrow 对 struct 不同字段的可变引用

获取与父字符串相关的&;str的原始片段

无法实现整型类型的泛型FN

更合理的方法来设计样条线函数器?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

这个不安全的 Rust 代码有什么问题,所以它可以在 Windows 上运行,但不能在 Ubuntu 上运行?

为什么 Rust 创建的 f32 小于 f32::MIN_POSITIVE?

从 rust 函数返回 &HashMap

我们可以在 Rust 切片中使用步骤吗?

如何判断服务器是否正确接收数据

如何使返回 XMLError 的方法与 anyhow::Error 兼容?

如何在 Rust 中创建最后一个元素是可变长度数组的 struct ?

当我在 struct 中存储异步函数时,为什么它需要生命周期

Rustlings 切片原语

为什么当borrow 变量发生变化时,borrow 变量不会改变?

Rust:为什么在 struct 中borrow 引用会borrow 整个 struct?