Inteligentne wskaźniki
Wskaźnik to ogólne pojęcie dla zmiennej, która zawiera adres w pamięci. Ten adres odwołuje się do, czyli „wskazuje na”, inne dane. Najczęstszym rodzajem wskaźnika w Rust jest referencja, o której uczyłeś się w Rozdziale 4. Referencje są wskazywane symbolem & i pożyczają wartość, na którą wskazują. Nie mają żadnych specjalnych możliwości poza odwoływaniem się do danych i nie mają żadnych narzutów.
Inteligentne wskaźniki natomiast to struktury danych, które zachowują się jak wskaźnik, ale mają również dodatkowe metadane i możliwości. Koncepcja inteligentnych wskaźników nie jest unikalna dla Rusta: inteligentne wskaźniki powstały w C++ i istnieją również w innych językach. Rust posiada różnorodne inteligentne wskaźniki zdefiniowane w standardowej bibliotece, które zapewniają funkcjonalność wykraczającą poza tę zapewnianą przez referencje. Aby zbadać ogólne pojęcie, przyjrzymy się kilku różnym przykładom inteligentnych wskaźników, w tym typowi inteligentnego wskaźnika z licznikiem referencji. Ten wskaźnik umożliwia posiadanie wielu właścicieli danych poprzez śledzenie liczby właścicieli i, gdy nie ma już właścicieli, oczyszczanie danych.
W Rust, z jego koncepcją własności i pożyczania, istnieje dodatkowa różnica między referencjami a inteligentnymi wskaźnikami: podczas gdy referencje tylko pożyczają dane, w wielu przypadkach inteligentne wskaźniki posiadają dane, na które wskazują.
Inteligentne wskaźniki są zazwyczaj implementowane za pomocą struktur. W przeciwieństwie do zwykłej struktury, inteligentne wskaźniki implementują cechy Deref i Drop. Cecha Deref pozwala instancji struktury inteligentnego wskaźnika zachowywać się jak referencja, dzięki czemu można pisać kod, który działa zarówno z referencjami, jak i inteligentnymi wskaźnikami. Cecha Drop pozwala dostosować kod, który jest uruchamiany, gdy instancja inteligentnego wskaźnika wychodzi poza zakres. W tym rozdziale omówimy obie te cechy i zademonstrujemy, dlaczego są one ważne dla inteligentnych wskaźników.
Biorąc pod uwagę, że wzorzec inteligentnego wskaźnika jest ogólnym wzorcem projektowym często używanym w Rust, ten rozdział nie obejmie każdego istniejącego inteligentnego wskaźnika. Wiele bibliotek ma własne inteligentne wskaźniki, a nawet możesz napisać własny. Omówimy najbardziej popularne inteligentne wskaźniki w standardowej bibliotece:
Box<T>, do alokowania wartości na stercieRc<T>, typ zliczający referencje, który umożliwia wielokrotne posiadanieRef<T>iRefMut<T>, dostępne przezRefCell<T>, typ, który wymusza zasady pożyczania w czasie działania zamiast w czasie kompilacji
Ponadto omówimy wzorzec wewnętrznej zmienności, w którym niezmienny typ udostępnia API do mutowania wartości wewnętrznej. Omówimy również cykle referencji: jak mogą prowadzić do wycieków pamięci i jak im zapobiegać.
Zaczynajmy!