数理論理学とコンピュータサイエンスの分野である型理論では、ユニット型は1 つの値のみを許可する型(したがって、情報を保持できない型)です。ユニット型に関連付けられたキャリア(基礎となるセット)は、任意のシングルトン セットにすることができます。このような 2 つのセットの間には同型性があるため、ユニット型について話し、その値の詳細については無視するのが通例です。ユニット型を 0タプルの型、つまり型の 積と見なすこともできます。
ユニット型は、型と型付き関数のカテゴリにおける終端オブジェクトです。ゼロまたは空の型と混同しないでください。ゼロまたは空の型は値を許可せず、このカテゴリの初期オブジェクトです。同様に、ブール型は2 つの値 を持つ型です。
ユニット型は、ほとんどの関数型プログラミング言語で実装されています。一部の命令型プログラミング言語で使用されるvoid 型は、その機能の一部を提供しますが、キャリア セットが空であるため、いくつかの制限があります (詳細は以下を参照)。
プログラミング言語では
いくつかのコンピュータプログラミング言語では、副作用を引き起こすことのみを目的とした関数の結果の型と、引数を必要としない関数の引数の型を指定するためのユニット型が提供されています。
- Haskell、Rust、Elmでは、ユニット型は と呼ばれ
()、その唯一の値も であり()、0 タプルの解釈を反映しています。 - ML の派生クラス ( OCaml、Standard ML、F#を含む)では、型は と呼ばれます
unitが、値は として記述されます()。 - Scalaでは、ユニット型は と呼ばれ
Unit、その唯一の値は として記述されます()。 - Common Lispでは、 NULLという型は、シンボルNILという 1 つの値を持つ単位型です。これは、最下位の型であるNIL型と混同しないでください。
- Pythonには、
NoneTypeという単一の値を許可する という型がありますNone。Python のオプションの静的型注釈では、この型は として表されますNone。[1] - Swiftでは、ユニット型は
Voidまたは と呼ばれ()、その唯一の値も であり()、0 タプルの解釈を反映しています。 - Javaでは、ユニット型は と呼ばれ
Void、その唯一の値は ですnull。 - Goでは、ユニット タイプが記述され
struct{}、その値は ですstruct{}{}。 - PHPでは、ユニット型は null と呼ばれ、その値のみが NULL になります。
- JavaScriptでは、
Null(唯一の値はnull) とUndefined(唯一の値はundefined) は両方とも組み込みの単位型です。 - Kotlinでは、オブジェクト
Unitという 1 つの値のみを持つシングルトンですUnit。 - Rubyでは、はクラス
nilの唯一のインスタンスですNilClass。 - C++では、
std::monostateユニット型は C++17 で追加されました。それ以前は、 などの空の構造体を使用してカスタム ユニット型を定義することができましたstruct empty{}。
ユニット型としてのボイド型
C、C++、C#、D、およびPHPでは、はvoid、有用なものを何も返さない関数、または引数を受け入れない関数を指定するために使用されます。 C のユニット型は概念的には空の に似ていますstructが、メンバーのない構造体は C 言語仕様では許可されていません (これは C++ では許可されています)。代わりに、 ' void' は、ユニット型のプロパティの一部 (すべてではありません) をシミュレートする方法で使用されます。詳細は以下を参照してください。ほとんどの命令型言語と同様に、C では値を返さない関数が許可されています。これらは、 void 戻り値型を持つように指定されます。このような関数は、Pascalなどの他の命令型言語ではプロシージャと呼ばれ、関数とプロシージャの間には型システムの区別ではなく構文上の区別が行われます。
呼び出し規約の違い
真のユニット型と void 型の最初の顕著な違いは、ユニット型は常に関数の引数の型になる可能性があるのに対し、void 型はリスト内で唯一の引数として表示される可能性があるにもかかわらず、C の引数の型になることができないことです。この問題は、C のコンパイル時エラーである次のプログラムで最もよく示されています。
void f ( void ) {} void g ( void ) {}
int main ( void ) { f ( g ()); // ここでコンパイル時エラーが発生します return 0 ; }
この問題は、C 言語のほとんどのプログラミングでは発生しません。void型には情報がないため、渡しても意味がないからです。しかし、 C++テンプレートなどの汎用プログラミングでは、型を他の型とは異なる方法で扱う必要がある場合に発生する可能性があります。ただし、C++ では空のクラスが許可されているため、実際のユニット型を実装できます。上記の例は、次のようにコンパイル可能になります。
void
クラスunit_type {}; const unit_type the_unit ;
unit_type f ( unit_type ) {ユニットを返します; } unit_type g ( unit_type ) {ユニットを返します; }
int main () { f ( g ( the_unit )); 0 を返す; }
(簡潔にするために、上記の例では がthe_unit本当にシングルトンであるかどうかは気にしていません。その問題の詳細については、
シングルトン パターンを参照してください。)
ストレージの違い
2 つ目の注目すべき違いは、void 型は特殊であり、レコード型、つまり C/C++ の構造体やクラスに格納できないことです。対照的に、ユニット型は関数型プログラミング言語のレコードに格納できます。つまり、フィールドの型として表示できます。C++ でのユニット型の上記の実装も格納できます。これは役に立たない機能のように思えるかもしれませんが、たとえば、ユニット型へのマップとしてセットをエレガントに実装できます。ユニット型がない場合でも、各キーに別の型のダミー値を格納することで、この方法でセットを実装できます。
ジェネリック医薬品
VoidJava Generics では、型パラメータは参照型でなければなりません。ユニット型パラメータが必要な場合、ラッパー型がよく使用されます。このVoid型はインスタンスを持つことはできませんが、null他のすべての参照型と同様に 1 つの値を持つため、ユニット型として機能します。実際には、 などのインスタンス化できない他の型も、Mathという 1 つの値を持つため、この目的で使用できますnull。
パブリックスタティックVoid f ( Void x ) {戻り値 null ; }パブリックスタティックVoid g ( Void x ) {戻り値 null ; }
パブリック静的void main ( String [] args ) { f ( g ( null )); }
ヌル型
静的に型付けされた言語は、すべての可能な式に型を与えます。null式に型を関連付ける必要があります。null に対して型が定義され、この値のみを持ちます。
たとえば、D ではnullのみを返す関数を宣言できます。
typeof ( null ) returnThatSpecialThing (){ return null ; }
nullは、ユニット型である typeof(null)が持つことができる唯一の値です。
参照
- シングルトン パターン(特定のクラスにはインスタンスが 1 つしか存在しないが、そのクラスへの狭義の非 null 参照は、通常、他のクラスによって保持されない)
注記
- ^ van Rossum, Guido; Levkivskyi, Ivan. 「PEP 483 - None の使用」。Python機能強化提案。Python Software Foundation。2024年3 月 2 日閲覧。
参考文献
- ピアス、ベンジャミン C. (2002)。型とプログラミング言語。MITプレス。pp . 118–119。ISBN 0-262-16209-1。
- nラボのユニットタイプ
