Ma ona kilka zastosowań. Może być używany do funkcji, które są zaprojektowane do paniki lub wyjścia z programu. panic!()
sama jest jedną z takich funkcji, ale można ją również zastosować do funkcji, które obejmują panic!()
, takich jak drukowanie bardziej szczegółowych informacji o błędach, a następnie panikowanie.
Może być również używany do funkcji, które nigdy nie powrócą. Jeśli funkcja przechodzi do nieskończonej pętli, takiej jak główna pętla serwera, a zatem nigdy nie wraca, może zostać zdefiniowana w ten sposób.
Innym możliwym zastosowaniem będzie opakowanie wokół Unixa exec
family of functions, w którym bieżący proces zostanie zastąpiony bieżącym procesem.
Przydaje się taki typ, ponieważ jest zgodny z wszystkimi innymi typami. Aby być bezpiecznym w typie, Rust musi upewnić się, że wszystkie gałęzie oświadczenia match
lub if
zwracają ten sam typ. Ale jeśli istnieją jakieś gałęzie, które są nieosiągalne lub wskazują na błąd, potrzebny jest sposób na zgłoszenie błędu, który zostanie ujednolicony z typem zwracanym przez inne gałęzie. Ponieważ !
ujednolica ze wszystkimi typami, może być użyty w każdym takim przypadku.
Jest interesting RFC (i discussion) w chwili, gdy twierdzi, (w części) do expanding the places where !
can be used, twierdząc, że powinna być traktowana jako w pełni rozwiniętym typu jak ()
IS; !
jest typem bez wartości jednoczących się ze wszystkimi pozostałymi typami, natomiast ()
jest typem odrębnym o pojedynczej wartości. Nie jestem pewien, czy zgadzam się z pełnym RFC, ale dyskusja o traktowaniu !
jako typu pełnoprawnego jest interesująca i myślę, że mogłaby być zaproponowana oddzielnie od reszty specyfikacji RFC.
Aktualizacja: Ponieważ napisałem wyżej, część RFC o promowanie !
do pełnego typu rozwiniętego był split into a separate RFC and merged i jest in the process of being implemented (obecnie dostępny w nightly buduje za bramą fabularnym). Jako pełnoprawny typ można go stosować w większej liczbie kontekstów, na przykład w Result<T, !>
, wskazując wynik, który nigdy nie zawiedzie, lub Result<!, E>
jako taki, który nigdy nie może się powieść. Są użyteczne w ogólnych kontekstach; jeśli masz jakąś cechę, która wymaga metody zwracania wyniku, ale dla tej konkretnej implementacji może się to tylko udać, nie musisz wypełniać jakiegoś fałszywego typu błędu.
Moje ulubione to 'unimplemented!()' I 'unreachable!()'. – Shepmaster