7.1 nullが表すもの

nullは一般に「値が存在しない」ことを表します。

しかし、実際には複数の意味で使われがちです。

まだ設定されていない
検索しても見つからなかった
意図的に空にした
取得に失敗した
利用権限がない

これらをすべてnullで表すと、意味が曖昧になります。


7.2 Nullable型

値が存在する場合と、存在しない場合を型として表します。

function findUser(int $id): ?User
{
}
function findUser(id: number): User | null
{
}
fun findUser(id: Int): User?

7.3 Option型・Maybe型

Rustでは、値の有無を明示的な直和型で表します。

enum Option<T> {
    Some(T),
    None,
}

使用例です。

fn find_user(id: u64) -> Option<User> {
    // Some(user) または None
}

呼び出し側は、両方のケースを処理します。

match find_user(1) {
    Some(user) => println!("{}", user.name),
    None => println!("not found"),
}

Option型は、「値がない可能性」を通常値とは別の構造として扱います。


7.4 Null安全構文

多くの言語に、nullの場合は処理を中断する構文があります。

$country = $user?->address?->country;
const country = user?.address?.country;
val country = user?.address?.country

デフォルト値を使う構文もあります。

$name = $user->name ?? 'guest';
name = user.name if user is not None else "guest"
let name = optional_name.unwrap_or("guest");

重要なのは記号ではなく、次の意味です。

値が存在するなら処理する
存在しないなら安全に別の値へ分岐する