unsafe 関数の定義

// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0
/// null になりうるポインタを参照に変換します。
///
/// `p` が null の場合は `None` を返し、そうでない場合は `val` を `Some` でラップして返します。
fn ptr_to_ref<'a, T>(ptr: *mut T) -> Option<&'a mut T> {
    if ptr.is_null() {
        None
    } else {
        // SAFETY: `ptr` は null ではない
        unsafe { Some(&mut *ptr) }
    }
}

「これは安全なコードのように見えますが、実際には unsafe ブロックが必要です。」

逆参照操作、つまり unsafe ブロック内の *p を強調してください。

「呼び出し側は、ptr が null であるか、または参照に変換できる ことを保証しなければなりません。

「直感に反するかもしれませんが、多くのポインタは参照に変換でき ません。

「たとえば、有効な値ではなく任意のビット列を指すポインタが作られ る可能性があります。これは Rust が許容しないことであり、この関数 はそのような事態から自身を守る必要があります。

「そのため、API 設計者としては 2 つの道があります。無効な入力を 防ぐ責任を自分たちで負うようにするか、unsafe キーワードによって その責任を呼び出し側に移すかです。」

「1 つ目の道は困難です。受け入れているのはジェネリック型 T、つまり Sized を実装するあらゆる型だからです。これは非常に多くの型です!

「したがって、2 つ目の道のほうが理にかなっています。

追加コンテンツ(時間があれば)

「ちなみに、ポインタの詳細や、それらを参照に変換する際のルールに 興味があるなら、標準ライブラリには有用なドキュメントがたくさん あります。さらに、std::pointer にある多くのメソッドのソースコード も確認するとよいでしょう。

「たとえば、このスライドの ptr_to_ref 関数は、実際には標準 ライブラリでポインタの as_mut メソッドとして存在します。」

std::pointer.as_mut のドキュメントを開いて、Safety セクションを強調してください。