不安全的Rust

这是一个严肃、巨大、复杂和危险的话题。它是如此严重,以至于关于它,我写了 一整本书

长话短说,只要你允许调用其他语言,每一种语言实际上都是不安全的,因为你可以让C做任 意的坏事。是的:Java、Python、Ruby、Haskell......每个人在面对外来函数接口(FFI)的 时候都是很不安全的。

Rust通过将自己分成两种语言来接受这一事实。安全的Rust和不安全的Rust。到目前为止,我 们只使用了安全的Rust。它是完全100%安全的......除了它可以FFI到不安全的Rust。

不安全的Rust是安全Rust的一个超集。它的所有语义和规则与安全Rust完全相同,你只是被 允许做一些额外的事情,这些事情是非常不安全的,可能会导致可怕的未定义行为,困扰着C。

同样,这是一个非常巨大的话题,有很多有趣的角落案例。我真的不想深入研究它(好吧,我 其实想。我已经研究了。读那本书)。这没关系,因为有了链表,我们实际上可以忽略 几乎所有的东西。

我们要使用的主要不安全工具是原始指针。原始指针基本上是C的指针。它们没有固有的别名规 则。它们没有生命期。它们可以是空的。它们可以是悬空的。它们可以指向未初始化的内存。它 们可以被转换为整数或从整数中转换。它们可以被转换为指向不同的类型。可变性?转换它。几 乎所有的东西都可以,这意味着几乎所有的东西都可能出错。

这是一些不好的东西,老实说,要是永远不用碰这些东西,你会活得更快乐。不幸的是,我们想写 链表,而链表是很糟糕的。这意味着我们将不得不使用不安全的指针。

有两种类型的原始指针:*const T*mut T。这些是指C语言中的const T*T*,但 我们真的不关心 C 语言认为它们是什么意思。你只能将*const T解除引用为&T,但就像变 量的可变性一样,这只是对不正确使用的一种提示。最多只是意味着你必须先将*const转为 *mut。尽管如果你实际上没有权限去改变指针的引用,你会有一个糟糕的时间。

总之,当我们写一些代码时,我们会对此有更好的感觉。现在, *mut T == &unchecked mut T