2014-07-19 15 views
17

Rust ma jednostkę typu typu, (), typ o pojedynczej wartości zerowej. Wartość tego typu jednostki jest również określona przy użyciu ().Jaki jest cel typu jednostki w Rust?

Jaki jest cel typu jednostki i jej wartość? Czy jest to mechanizm, który pozwala uniknąć używania null (lub nil) jak to mają inne języki?

+1

To bardziej przypomina 'void' w językach podobnych do C. O ile mi wiadomo, wszystko jest wyrazem rdzy, więc '()' jest wartością zwracaną przez coś, co jest wykonywane tylko dla jej efektów. – Lee

+0

Możesz tworzyć własne typy o zerowym rozmiarze, podobnie jak '()', wypowiadając 'struct MyNewZeroSizeType;' Może być użyteczne ("typy znaczników"!) – bluss

+1

To nie wygląda na 'null' w java, ponieważ jeśli powiedz, że zwracasz 'int', którego nie możesz zwrócić'() 'zamiast tego. – JustGage

Odpowiedz

25

() jest wartością typu () i jej celem jest być bezużytecznym.

Wszystko w Rust jest wyrażeniem, a wyrażenia, które zwracają "nic", w rzeczywistości zwracają (). Kompilator zgłosi błąd, jeśli masz funkcję bez typu zwracanego, ale mimo to zwróci ona coś innego niż (). Na przykład:

fn f() { 
    1i // error: mismatched types: expected `()` but found `int` 
} 

Istnieją również praktyczne zastosowania dla (). Czasami nie interesuje nas rodzaj ogólny, a () czyni to wyraźnym.

Na przykład: Result<(), String> może być używany jako typ zwracany dla funkcji, która z powodzeniem kończy się pomyślnie lub kończy się niepowodzeniem.

+0

W przypuszczam, że można również zdefiniować metody dla niego, ale nie będzie żadnego stanu z tymi ... Czy to prawda? – errordeveloper

+1

@errordeveloper tak, prawie wszystko co możesz zrobić z '()' ma trywialną implementację. – huon

7

Jeśli pochodzisz z języka podobnego do języka C (C, C++, Java itp.), Możesz myśleć o jednostce jako o void. Jest to typ, który powracasz, gdy nie chcesz niczego zwracać.

Teoretycy typu będą wskazywać, że jednostka nie jest pusta, ponieważ jednostka ma dokładnie jedną wartość, podczas gdy void ma 0 wartości.

W praktyce ilość informacji, które można przechowywać w obu typach, jest taka sama (0 bitów), chociaż języki, w których używa się jednostki, wydają się być przyjemniejsze w obsłudze, ponieważ można traktować je tak samo, jak każdą inną wartość.

Możesz przechowywać go w zmiennej, strukturze, kolekcji lub gdziekolwiek indziej, gdzie możesz zapisać wartość. Możesz przekazać jako argument lub zwrócić go w wyniku. Możesz utworzyć odniesienie do niego. Itd.

Kiedy jest to przydatne? Głównie wtedy, gdy nie obchodzi cię, z jakim typem wartości masz do czynienia. Oznacza to, że można pisać kod polimorficzny/ogólny, nie martwiąc się o to, czy wartość, z którą mamy do czynienia, faktycznie zawiera jakąkolwiek informację. Tj. Nie ma potrzeby specjalnego przypadku, jeśli przechowujesz aktualne dane lub ().

Jednym z przykładów użycia tej opcji jest HashSet. A HashSet<T> jest faktycznie zaimplementowany jako a thin wrapper around HashMap<T,()>. (Mapa typu ogólnego: T do ())