web-dev-qa-db-ja.com

Rustのユニットタイプの目的は何ですか?

Rustにはユニットタイプ()があり、サイズがゼロの値が1つだけのタイプです。この単位タイプの値も()を使用して指定されます。

ユニットタイプとその値の目的は何ですか?他の言語のようにnull(またはnil)の使用を回避するメカニズムですか?

35
Will

_()_は_()_型の値であり、その目的は役に立たないことです。

Rustはすべて式であり、 "nothing"を返す式は実際には_()_を返します。戻り値の型のない関数があり、他の値を返す場合、コンパイラはエラーを返しますとにかく_()_より。たとえば

_fn f() {
    1i32 // error: mismatched types: expected `()` but found `int`
}
_

_()_の実用的な用途もあります。ジェネリック型を気にしないこともあり、_()_はこれを明示的にします。

たとえば、Result<(), String>は、さまざまな理由で正常に完了または失敗する関数の戻り型として使用できます。

46
A.B.

Cのような言語(C、C++、Javaなど)から来ている場合は、ユニットをvoidのように考えることができます。何も返さない場合に返すタイプです。

型理論家は、ユニットの値が1であるのに対してvoidの値は0であるため、ユニットはvoidとは異なることを指摘します。

実際には、両方のタイプに格納できる情報の量は同じ(0ビット)ですが、unitを使用する言語は、他の値と同じように扱うことができるので、より使いやすい傾向があります。

変数、構造体、コレクション、または値を格納できる他の場所に格納できます。引数として渡すか、結果として返すことができます。それへの参照を作成できます。等。

それで、それはいつ役に立ちますか?主にあなたが扱っている値のタイプが気にならない場合。つまり、処理する値に実際に情報が含まれているかどうか、つまり、実際のデータを格納しているか_()_を格納しているかについて特別なケースを必要としないかどうかを気にすることなく、ポリモーフィック/ジェネリックコードを記述できます。

これが使用される場所の1つの例は、HashSetです。 _HashSet<T>_は実際には HashMap<T, ()> の薄いラッパーとして実装されます。 (ジェネリック型Tから_()_へのマップ)

21
aij