Nullable型
この項目「Nullable型」は翻訳されたばかりのものです。不自然あるいは曖昧な表現などが含まれる可能性があり、このままでは読みづらいかもしれません。(原文:英語版 Psu256 19:03, 16 August 2019) 修正、加筆に協力し、現在の表現をより自然な表現にして下さる方を求めています。ノートページや履歴も参照してください。(2020年6月) |
Nullable型、Null許容型 (英: nullable type) は、一部のプログラミング言語の機能であり、 データ型の通常の値の代わりに、値を特殊な値Nullに設定できる。静的型付け言語では、Nullable型はOption型だが、動的型付け言語(値には型があるが変数にはない)では、単一のnull値を持つことで同等の動作が提供される。
Nullは、SQLにおけるNULLのように、返されなかった関数やデータベースのフィールドの欠落などから、欠落した値または無効な値を表すためによく使用される。
整数型やブーリアン型などのプリミティブ型は通常nullにすることはできないが、対応するNullable型(Nullable整数およびNullableブーリアン型)はNull値をとることができる。
例
[編集]整数変数は(有限範囲の)整数を表すが、0 (ゼロ) を特殊なケースとして扱うことがある。これは、C言語を始めとする多くのプログラミング言語で、0が真偽値の "false" を意味する場合があるためである。ただし、これは変数が空(無効)であることが明示されず、有効な値としての0と区別ができないという欠点があるが、多くの状況では区別が必要になる。これを実現するのがNullable型である。
C#ではクラスなどの参照型はnull値をとることができるものの、組み込みの整数型int
などに代表される構造体のような値型(System.ValueType
から派生する特殊なオブジェクト型)はnull値をとることができない。C# 2.0以降では、たとえば、Nullable整数は疑問符を用いて int? x
で宣言できる[1]。T?
は内部的にはジェネリクス型System.Nullable<T>
のエイリアスであり、前記の例は System.Nullable<int> x
として展開される。ジェネリクス機能を持たないC# 1.0では、いくつかのユーザー定義のNullable型を提供する外部ライブラリ[2]もあった(例: NullableInteger、NullableBoolean)[3]。
ブール変数は効果がより明確に表れる。値は "true" または "false" のいずれかだが、Nullableブール値には "undecided"(未決定)の表現も含まれる場合がある(3値論理)。ただし、そのような変数を含む論理演算の解釈または処理は、言語によって異なる。
Javaには、int
、boolean
、float
などの(null値をとることができない)各プリミティブ型に対応するInteger
、Boolean
、Float
などのプリミティブラッパークラスがあり、これらはnull値をとることができるため、Nullable型の代用として利用できる。さらに自動ボックス化(オブジェクトと値の間の使用法に基づく自動変換)と組み合わせることで効果を発揮する。
nullポインタとの比較
[編集]プリミティブ型とは対照的に、オブジェクトポインタまたはオブジェクト参照は、ほとんどの一般的な言語ではデフォルトでNULLに設定できる。これは、ポインタまたは参照がどこも指さないこと、オブジェクトが割り当てられないこと(変数がオブジェクトを指さないこと)を意味する。Nullable参照は、1965年にアントニー・ホーアによってAlgol W言語の一部として発明された。ホーアは後に彼の発明を「10億ドルの間違い」と表現した[4]。これは、NULLの可能性があるオブジェクトポインタは、ユーザがポインタを使用する前に確認する必要があり、オブジェクトポインタがNULLの場合を処理するために特定のコードが必要になるためである[注釈 1]。
逆に後発の言語では、既定でオブジェクト型を非Null許容 (non-nullable) とし、Nullableにするためには追加のコード(変数宣言時の型修飾や利用前のNullチェックの記述など)が必要となるものが多い。非Nullable型と静的なコード解析を組み合わせることで「Null安全」(null safety) を実現している。
Option型との比較
[編集]Nullable型の実装は通常、Nullオブジェクトパターンに従う。
Nullable型の概念を拡張する、より一般的で厳格な概念があるが、これは例外的なケースの明示的な処理を強制するOption型に由来するものである。Option型の実装は、通常は特殊なケースパターン(Special Case pattern)に従う[5]。
言語ごとのサポート
[編集]次のプログラミング言語は、Nullable型をサポートしている。
ネイティブ(言語組み込み)でのNullableサポートのある静的型付け言語には、次のものがある。内部的には標準ライブラリによってジェネリック型として実装されており、それを利用する糖衣構文として用意されていることも多い。
- Ballerina[6]
- Kotlin[7]
- Ceylon
- C#: Null許容の値型はバージョン2.0以降[1]、Null許容/非許容の参照型はバージョン8.0以降[8][注釈 2]
- SQL
- Swift[9]
- SAS(欠損値)
- VB.NET: null (
Nothing
) 許容の値型をバージョン2008 (VB.NET 9.0) 以降でサポート[10][11]
ライブラリによってNullableをサポートする静的型付け言語には、次のものがある。
- Java: バージョン8以降(
java.util.Optional
) - Scala
- Oxygene
System.Nullable
をサポートする.NET Framework 2.0以降あるいは.NET Core上で動作する、静的に型付けされたCLI言語全般[12]- C++: C++17以降(Boost C++ライブラリのBoost.Optionalが
std::optional
として標準化された)
nullを含む動的型付け言語には、次のものがある。
- Perl: スカラー変数のデフォルトでは
undef
があり、undef
を代入できる - PHP: NULL型、is_null()メソッド、バージョン7.1のネイティブnull許容型[14]
- Python:
None
値がある[15] - Ruby: nil値とNilClass型
- JavaScript:
null
値がある
脚注
[編集]注釈
[編集]- ^ C言語やC++では、NULLをデリファレンスすると未定義の動作を引き起こすため、必ず避けるようにコーディングしなければならない。JavaやC#では、nullをデリファレンスすると例外をスローすることが言語仕様で規定されているが、デリファレンス前にnullでないことを保証するのはプログラマーの責任である。
- ^ もともと、C#の値型 (value type) はnull非許容である一方、参照型 (reference type) はnull許容であった。しかし、nullを許容しない参照型を導入することで、静的コードチェックによりコードの完全性を担保するメリットが得られるため、C# 8.0では従来の参照型
T
をnull非許容型とし、T?
をnull許容型とするようにコンパイラオプションを構成することもできるようになった。ただし、デフォルトでは無効となっている。
出典
[編集]- ^ a b null 許容値型 - C# リファレンス | Microsoft Docs
- ^ “(luKa) Developer Zone - NullableTypes”. Nullabletypes.sourceforge.net. 2013年8月19日閲覧。
- ^ “NullableTypes”. Nullabletypes.sourceforge.net. 2013年8月19日閲覧。
- ^ http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
- ^ “P of EAA: Special Case”. Martinfowler.com. 2013年8月19日閲覧。
- ^ https://ballerina.io/learn/by-example/optional-type.html
- ^ Null safety | Kotlin
- ^ Null 許容参照型 - C# リファレンス | Microsoft Docs
- ^ Optional型 | Swiftの始め方
- ^ null 許容値型 - Visual Basic | Microsoft Docs
- ^ 新機能 - Visual Basic | Microsoft Docs
- ^ Nullable Class (System) | Microsoft Docs
- ^ null 許容値型 - F# | Microsoft Docs
- ^ https://wiki.php.net/rfc/nullable_types
- ^ https://docs.python.org/3/library/constants.html#None