2016-02-22 7 views

Odpowiedz

6

() to po prostu krotka bez wartości; 0-krotna. Typ i wartość są pisane tak samo, zarówno (). Typ jest czasem nazywany "typem jednostki"; W rzeczywistości był to typ odrębny w kompilatorze, ale teraz jest traktowany jako zdegenerowana krotka. Jest to typ o rozmiarze 0; obiekty tego typu nigdy nie zajmują żadnej przestrzeni, ale jest to typ Sized, tylko o rozmiarze 0.

Jest używany w przypadkach, gdy musisz mieć wartość lub typ, ale nie mają nic istotnego do umieszczenia tam. Na przykład, jeśli masz funkcję, która nie zwraca wartości i wywołujesz ją w miejscu, które oczekuje wartości, okazuje się, że rzeczywiście zwraca wartość () typu ().

fn nothing() {} 

fn main() { 
    println!("{:?}", nothing()); 
} 

która drukuje () (playpen).

Innym zastosowaniem jest typ ogólny, taki jak Result<T, E>, który wskazuje na sukces lub niepowodzenie niektórych operacji i może zawierać wynik pomyślnej operacji lub błąd wskazujący powód niepowodzenia. Niektóre operacje, takie jak std::io::write, które nie mają wartości do zwrócenia w przypadku powodzenia, ale chcą wskazać błąd, zwrócą wartość std::io::Result<()>, która jest w rzeczywistości synonimem dla Result<(), std::io::Error>; która pozwala funkcji zwracać Ok(()) w przypadku sukcesu, ale jakiś znaczący błąd, gdy się nie powiedzie.

Możesz porównać to do void w C lub C++, które są również używane do braku wartości zwracanej. Jednak nigdy nie można napisać obiektu o typie void, który powoduje, że void jest znacznie mniej użyteczny w programowaniu ogólnym; nigdy nie można mieć odpowiednika typu: Result<void, Error>, ponieważ nigdy nie można było skonstruować przypadku Ok.

W tym przypadku Mutex normalnie opakowuje i obiekt, do którego chcesz uzyskać dostęp; więc możesz umieścić ten obiekt w muteksie, a następnie uzyskać do niego dostęp od strażnika, który otrzymasz po zablokowaniu muteksa.Jednak w tym przykładzie nie ma rzeczywistych danych, które są strzeżone, więc () jest używany, ponieważ trzeba coś tam umieścić, a Mutex jest ogólny nad typem, aby mógł akceptować dowolny typ.

+0

Może dodać pojęcie "pustki"? Większość programistów zna "pustkę", więc to pomogłoby, prawda? –

+1

@LukasKalbertodt: Koszt "unieważnienia" jest jednak nieregularny. W programowaniu C++ szablon, na przykład "void", jest koszmarem. Z drugiej strony '()' jest doskonale zintegrowany z systemem typu => to tylko krotka jak każda inna. –

+0

@ MatthieuM. Racja, ale ** ja ** nadal uważam, że pomogłoby to programistom pochodzącym z innych języków porównać go z 'void' ... –

8

() to pusty tuple, zwany także unit type - krotka bez typów prętów. Jest to również jedyna ważna wartość wspomnianego typu. Ma on a size of zero (zauważ, że nadal jest to Sized, tylko o rozmiarze 0), co sprawia, że ​​nie występuje w środowisku wykonawczym. Ma to kilka użytecznych efektów, z których jeden jest tutaj używany.

Tutaj () służy do tworzenia Mutex bez posiadanych danych - jest to po prostu możliwy do odblokowania i blokowany muteks. Jeśli mamy wyraźnie wypisać wnioskowanie typu z turbofish operator::<>, możemy również napisać:

Mutex::<()>::new(()) 

Oznacza to, że mamy do tworzenia newMutex zawierający () z wartością początkową ().

+0

Zawsze zastanawiałem się, jak nazywa się tę składnię ... fajny link. – squiguy

+0

Tak, to jedna z moich ulubionych rzeczy o Rust ... Próbuję posypać ją wszędzie, gdzie mogę, aby stała się bardziej dostępna do wyszukiwania. – thirtythreeforty

+0

Pomocne może być również sprawdzenie, czy typy o zerowym rozmiarze, takie jak te, liczą się jako "Rozmiar", czy nie. (Tak, prawda?) – LinearZoetrope

Powiązane problemy