programowanieBackend Developer

Wyjaśnij, jak działa system własności (ownership) w Rust i jak zapewnia bezpieczeństwo pamięci bez garbage collectora?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

System własności (ownership) to podstawowa koncepcja Rust, która zapewnia bezpieczeństwo pamięci na etapie kompilacji. Każda zmienna ma właściciela. W danym momencie czasu może istnieć tylko jeden właściciel zasobu.

Własność jest przenoszona (move) przy przypisaniu lub przekazaniu do funkcji. Po przeniesieniu poprzedni właściciel nie może używać wartości:

let s = String::from("hello"); let t = s; // s jest już niedostępne

Rust odróżnia także pożyczanie (referencje).

  • &T — referencja tylko do odczytu (borrow).
  • &mut T — zmienialna referencja (mutable borrow), ale w danym czasie może istnieć tylko jedna.

Dzięki tym zasadom Rust gwarantuje, że nie wystąpią wyścigi danych, używanych po zwolnieniu pamięci i inne błędy zarządzania zasobami.

Pytanie podchwytliwe

Czy może istnieć więcej niż jedna zmienialna referencja (&mut T) jednocześnie dla jednej wartości? Dlaczego?

Odpowiedź: Nie, w danym momencie może istnieć albo dowolna liczba niezmienialnych referencji, albo tylko jedna zmienialna. To zapobiega wyścigom danych. Przykład błędnego kodu:

let mut s = String::from("hi"); let r1 = &mut s; let r2 = &mut s; // błąd kompilacji!

Przykłady rzeczywistych błędów z powodu nieznajomości tematu


Historia

W jednym projektcie wielowątkowym programista próbował przechowywać referencje do zmienialnego bufora, nie stosując własności, co prowadziło do awarii (use-after-free), gdy bufor był zwalniany przed zakończeniem pracy z referencją. Rust nie pozwolił na skompilowanie takiego kodu, więc konieczne było zmienienie architektury.


Historia

Na początku dużego projektu Rust programiści migrowali kod z C++. Próbowali łączyć przestarzałe przyzwyczajenia pracy z "surowymi" wskaźnikami, co prowadziło do błędów z własnością zasobów i stałych panik borrow checkera, aż do rozwiązania architektonicznego problemu własności.


Historia

W bibliotece do parsowania stringów błędy związane z podwójnym zwolnieniem pamięci udało się uniknąć tylko dzięki ścisłemu systemowi własności Rust. Analogiczna biblioteka w C++ prowadziła do trudnych do uchwycenia błędów i wycieków pamięci.