Unsafe Rust
これは深刻で、大きく、複雑で、危険なトピックです。 あまりに深刻なので、これについてはまるごと別の本を書きました。
要するに、他の言語を呼び出すことを許可した途端、すべての言語は実際には unsafe になります。なぜなら、C に任意にひどいことをさせられるからです。そうです。Java、Python、Ruby、Haskell……Foreign Function Interface (FFI) の前では、誰もが途方もなく unsafe なのです。
Rust は、自身を 2 つの言語、Safe Rust と Unsafe Rust に分けることでこの真実を受け入れています。ここまで私たちは Safe Rust だけを扱ってきました。これは完全に 100% safe です……ただし、FFI で Unsafe Rust を呼び出せる点を除けば。
Unsafe Rust は Safe Rust のスーパーセットです。すべてのセマンティクスとルールにおいて Safe Rust と完全に同じですが、C に付きまとう恐ろしい未定義動作を引き起こしうる、途方もなく unsafe なことをいくつか追加で行うことが許されているだけです。
繰り返しますが、これは本当に巨大なトピックで、興味深いコーナーケースがたくさんあります。 私はこれについて本当に深く踏み込みたくありません(まあ、本当は踏み込みたいのですが。実際に踏み込みました。その本を読んでください)。大丈夫です。なぜなら連結リストでは、実のところそのほとんどすべてを無視できるからです。
ナレーター: これは嘘だったが、2015 年には真実に見えた。
私たちが使う主な Unsafe の道具は生ポインターです。生ポインターは基本的に C のポインターです。固有のエイリアシング規則はありません。ライフタイムもありません。null になれます。アラインメントがずれていることがあります。ダングリングになれます。初期化されていないメモリを指すことができます。整数との相互変換ができます。別の型を指すようにキャストできます。ミュータビリティ? キャストすればよいのです。ほとんど何でもありであり、それはつまり、ほとんど何でも悪い方向に進みうるということです。
ナレーター: 固有のエイリアシング規則がない、だって? ああ、若さゆえの無邪気さよ。
これはかなり厄介な代物であり、正直なところ、これらに一切触れずに済むなら、そのほうが幸せな人生を送れるでしょう。残念ながら、私たちは連結リストを書きたいのであり、連結リストはひどいものです。つまり unsafe ポインターを使わなければならないということです。
生ポインターには *const T と *mut T の 2 種類があります。これらは C の const T* と T* を意図したものですが、C がそれらをどういう意味だと考えているかについて、私たちは実際のところそこまで気にしません。*const T は &T としてしかデリファレンスできませんが、変数のミュータビリティとよく似ていて、これは誤った使用に対する lint にすぎません。せいぜい、最初に *const を *mut にキャストする必要がある、という意味でしかありません。もっとも、そのポインターの参照先をミューテートする権限が実際にはないなら、ひどい目に遭うことになります。
ともあれ、コードを書いていくうちに、これについてよりよい感触がつかめるでしょう。今のところは、
*mut T == &unchecked mut T です!