0Pricing
Learn Rust Coding · Lekcja

Inteligentne wskaźniki Box, Rc i Arc

Dowiedzą się Państwo, jak `Box` zapewniający alokację na stercie, `Rc` zapewniający współdzieloną własność oraz `Arc` zapewniający bezpieczną współdzieloną własność między wątkami zarządzają danymi.

Inteligentne wskaźniki Box, Rc i Arc to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 1 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 3 lekcji w sumie.

Czym są inteligentne wskaźniki?

System własności języka Rust świetnie zapewnia bezpieczeństwo pamięci, ale czasami potrzebna jest większa elastyczność. Właśnie wtedy przydają się inteligentne wskaźniki!

Inteligentne wskaźniki to struktury danych, które działają jak wskaźniki, ale zawierają również dodatkowe metadane i możliwości. Automatycznie zarządzają pamięcią, własnością i innymi zasobami.

Box: przechowywanie danych na stercie

Najprostszym inteligentnym wskaźnikiem jest Box<T>. Pozwala on przechowywać dane na stercie zamiast na stosie.

  • Stos: szybkie dane o stałym rozmiarze.
  • Sterta: wolniejsze dane o elastycznym rozmiarze, alokowane w czasie działania programu.

Gdy umieszczą Państwo wartość w Box, sam Box znajduje się na stosie, ale wskazywane przez niego dane są przechowywane na stercie.

Używanie Box do alokacji na stercie

Zobaczmy, jak Box przenosi dane na stertę. Jest to przydatne w przypadku dużych danych lub gdy ich rozmiar nie jest znany w czasie kompilacji.

Uruchom ten kod, aby zobaczyć, jak wartość zostaje umieszczona w obiekcie box.

fn main() {
  let x = 5; // x is on the stack
  let boxed_x = Box::new(x); // x's value is moved to the heap, boxed_x is on stack
  println!("Value on stack: {}", x);
  println!("Value in Box (on heap): {}", *boxed_x); // Dereference to get value
}

Kiedy używać Box

Box<T> może być przydatny w następujących sytuacjach:

  • Gdy mają Państwo typ, którego rozmiaru nie można określić w czasie kompilacji, i trzeba przechować go w miejscu o znanym, stałym rozmiarze.
  • Gdy mają Państwo dużą ilość danych i chcą przekazać własność bez kopiowania samych danych.
  • Gdy chcą Państwo posiadać obiekt traitu (np. Box<dyn Trait>).

Rc: wielu właścicieli (jeden wątek)

Zasady własności języka Rust oznaczają, że wartość ma zwykle tylko jednego właściciela. Co jednak zrobić, gdy kilka części programu musi „posiadać” te same dane?

Rc<T>, czyli Reference Counted, pozwala wielu właścicielom korzystać z danych w kontekście jednowątkowym. Śledzi liczbę odwołań wskazujących na dane.

Gdy liczba odwołań spadnie do zera, dane zostają usunięte.

Udostępnianie danych za pomocą Rc

Rc::clone() zwiększa licznik odwołań. Nie jest to głęboka kopia — metoda tworzy jedynie kolejny wskaźnik do tych samych danych.

Proszę zauważyć, że dane są współdzielone, a ich wartość jest dostępna z różnych „właścicieli”.

use std::rc::Rc;

fn main() {
  let value = Rc::new(String::from("Shared String"));
  println!("Count after creation: {}", Rc::strong_count(&value));

  let value_clone_a = Rc::clone(&value); // Increment count
  println!("Count after clone A: {}", Rc::strong_count(&value));

  {
    let value_clone_b = Rc::clone(&value); // Increment count
    println!("Count after clone B: {}", Rc::strong_count(&value));
    println!("Data from A: {}", value_clone_a);
    println!("Data from B: {}", value_clone_b);
  } // value_clone_b goes out of scope, count decreases

  println!("Count after B goes out of scope: {}", Rc::strong_count(&value));
}

Arc: współdzielona własność (wiele wątków)

Rc<T> dobrze sprawdza się w aplikacjach jednowątkowych. Jeśli jednak trzeba współdzielić dane między wieloma wątkami, Rc<T> nie jest bezpieczny.

Arc<T>, czyli Atomic Reference Counted, to bezpieczna dla wątków wersja Rc<T>. Używa operacji atomowych do aktualizowania licznika odwołań, zapewniając bezpieczeństwo między wątkami.

Arc ma nieco większy narzut wydajnościowy niż Rc ze względu na operacje atomowe.

Udostępnianie danych między wątkami za pomocą Arc

Ten przykład pokazuje, jak Arc pozwala wielu wątkom bezpiecznie uzyskiwać dostęp do tych samych współdzielonych danych i je odczytywać. Każdy wątek otrzymuje własną kopię `Arc`.

Wątek główny czeka na zakończenie wszystkich uruchomionych wątków.

use std::sync::Arc;
use std::thread;

fn main() {
  let data = Arc::new(vec![1, 2, 3, 4, 5]);
  let mut handles = vec![];

  for i in 0..3 {
    let data_clone = Arc::clone(&data); // Clone Arc for each thread
    let handle = thread::spawn(move || {
      println!("Thread {} has data: {:?}", i, *data_clone);
    });
    handles.push(handle);
  }

  for handle in handles {
    handle.join().unwrap();
  }
  println!("All threads finished.");
}

Box, Rc czy Arc?

Wybór odpowiedniego inteligentnego wskaźnika zależy od potrzeb:

  • Box<T>: gdy trzeba umieścić dane na stercie, zazwyczaj przy jednym właścicielu lub w przypadku typów rekurencyjnych.
  • Rc<T>: gdy dane mają mieć wielu właścicieli w kontekście jednowątkowym.
  • Arc<T>: gdy dane mają mieć wielu właścicieli w kontekście wielowątkowym (współbieżnym).

Jeśli bezpieczeństwo wątkowe nie jest potrzebne, należy zawsze preferować Box lub Rc, ponieważ Arc wiąże się z kosztem wydajnościowym.

Sprawdź wiedzę o inteligentnych wskaźnikach

Trzeba przechować duży plik obrazu na stercie, a tylko jedna część programu będzie jego właścicielem i będzie nim zarządzać. Którego inteligentnego wskaźnika należy użyć?

Podsumowanie: inteligentne wskaźniki

W tej lekcji poznali Państwo trzy podstawowe inteligentne wskaźniki języka Rust:

  • Box<T>: do alokowania danych na stercie przy jednym właścicielu.
  • Rc<T>: do umożliwiania wielu właścicielom danych w środowisku jednowątkowym.
  • Arc<T>: do umożliwiania wielu bezpiecznych dla wątków właścicieli danych w środowisku wielowątkowym.

Te inteligentne wskaźniki zapewniają większą kontrolę nad zarządzaniem pamięcią, jednocześnie wykorzystując gwarancje bezpieczeństwa języka Rust.

Często zadawane pytania

Czy lekcja „Inteligentne wskaźniki Box, Rc i Arc” jest bezpłatna?

Tak — pełny tekst „Inteligentne wskaźniki Box, Rc i Arc” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 3 lekcji w sumie.

Co nauczysz się w „Inteligentne wskaźniki Box, Rc i Arc”?

Dowiedzą się Państwo, jak `Box` zapewniający alokację na stercie, `Rc` zapewniający współdzieloną własność oraz `Arc` zapewniający bezpieczną współdzieloną własność między wątkami zarządzają danymi. Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?

Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 3.

Ile czasu zajmuje lekcja „Inteligentne wskaźniki Box, Rc i Arc”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?

Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Inteligentne wskaźniki Box, Rc i Arc
  2. Wewnętrzna mutowalność: RefCell, Cell
  3. Beztroska współbieżność z wątkami
← Powrót do Learn Rust Coding