0Pricing
Learn Rust Coding · Lezione

Comprendere il modello di ownership di Rust

Comprenda le regole fondamentali dell’ownership e la semantica degli spostamenti, nonché il modo in cui prevengono errori comuni di memoria come il double-free.

Comprendere il modello di ownership di Rust è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 1 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 3 lezioni in totale.

Che cos'è l'ownership in Rust?

Il sistema di ownership di Rust è un insieme di regole che gestisce il modo in cui il programma usa la memoria. È un concetto fondamentale che consente a Rust di garantire la sicurezza della memoria senza un garbage collector.

  • Nessun puntatore pendente.
  • Nessun errore di double free.
  • Nessuna race condition sui dati nel codice concorrente.

Rust verifica queste regole in fase di compilazione!

Memoria stack e heap

I programmi usano due aree principali della memoria: lo stack e lo heap.

  • Stack: dati più veloci e di dimensione fissa, come interi, booleani e tipi di dimensione nota. I dati vengono inseriti e rimossi in ordine.
  • Heap: dati più lenti e di dimensione variabile, come String e Vec. I dati vengono richiesti e restituiti dall'allocatore.

L'ownership gestisce principalmente i dati nello heap, garantendone l'uso e la liberazione sicuri.

Regola 1: ogni valore ha un proprietario

La prima regola dell'ownership è semplice: ogni valore in Rust ha una variabile chiamata proprietario.

Immagini di avere un'etichetta su una scatola. La variabile s qui sotto è il proprietario del testo "hello".

fn main() {
  let s = String::from("hello"); // s owns "hello"
  println!("{}", s);
}

Regola 2: un solo proprietario alla volta

La seconda regola stabilisce che: in qualsiasi momento può esserci un solo proprietario per un valore. Questo è fondamentale per prevenire i problemi di memoria.

Quando si assegna un valore complesso, come una String che risiede nello heap, da una variabile a un'altra, l'ownership viene trasferita, non copiata.

Il trasferimento dell'ownership in azione

Osservi cosa succede quando il valore di s1 viene assegnato a s2. Provi a eseguire il codice.

fn main() {
  let s1 = String::from("Hello, CoddyKit!");
  let s2 = s1; // Ownership of the String data moves from s1 to s2

  // println!("{}", s1); // This line would cause a compile-time error!
  println!("{}", s2);
}

Capire la semantica del "move"

Dopo let s2 = s1;, s1 non è più considerato valido. Rust impedisce di usare nuovamente s1.

  • Questo si chiama move. Il puntatore, la lunghezza e la capacità nello stack vengono copiati, ma i dati nello heap no.
  • Se s1 fosse ancora valido, sia s1 sia s2 tenterebbero di liberare la stessa memoria quando uscissero dall'ambito, causando un errore di double free.

Il sistema di ownership di Rust impedisce tutto questo in fase di compilazione!

Ownership e chiamate di funzione

Passare un valore a una funzione funziona in modo simile all'assegnarlo a un'altra variabile: l'ownership viene trasferita alla funzione.

Quando la funzione termina, il proprietario del valore, cioè il parametro della funzione, esce dall'ambito e il valore viene eliminato.

Dimostrazione dell'ownership nelle funzioni

Osservi come il valore String venga trasferito a takes_ownership e come gives_ownership restituisca una nuova String.

fn takes_ownership(some_string: String) {
  println!("Inside takes_ownership: {}", some_string);
} // some_string goes out of scope and `drop` is called.

fn gives_ownership() -> String {
  let some_string = String::from("returned string");
  some_string // Ownership is moved out of the function
}

fn main() {
  let s1 = String::from("hello");
  takes_ownership(s1); // s1's value moves into takes_ownership
  // println!("{}", s1); // Error: s1 is no longer valid here!

  let s2 = gives_ownership(); // s2 gets ownership of the returned String
  println!("After gives_ownership: {}", s2);
}

Regola 3: ambito ed eliminazione

L'ultima regola è: quando il proprietario esce dall'ambito, il valore viene eliminato.

  • Un ambito è l'intervallo di un programma in cui un elemento è valido, solitamente delimitato dalle parentesi graffe {}.
  • Quando una variabile esce dall'ambito, Rust chiama automaticamente una funzione speciale chiamata drop.

In questo modo la memoria viene ripulita automaticamente e in sicurezza, senza un garbage collector.

Prevenire gli errori di memoria

Le regole dell'ownership collaborano per garantire la sicurezza della memoria:

  • Un solo proprietario: impedisce a più parti del codice di tentare di liberare la stessa memoria.
  • Eliminazione alla fine dell'ambito: garantisce che la memoria venga liberata esattamente una volta e al momento corretto.

In questo modo si eliminano in fase di compilazione bug comuni come gli errori di double free e gli errori di utilizzo dopo la liberazione, per una maggiore tranquillità!

Verifica dell'ownership

Consideri il seguente codice Rust. Che cosa succederà quando proverà a compilarlo ed eseguirlo?

fn main() {
  let message = String::from("Rust is fun!");
  let greeting = message;
  println!("{}", message);
}

Riepilogo: nozioni di base sull'ownership

Ottimo lavoro! Ha imparato le regole fondamentali del sistema di ownership di Rust:

  • Ogni valore ha un proprietario.
  • Può esserci un solo proprietario alla volta.
  • Quando il proprietario esce dall'ambito, il valore viene eliminato.

Questo sistema previene gli errori comuni di memoria senza un garbage collector. Ora esploreremo il borrowing per condividere i dati senza trasferire l'ownership.

Domande Frequenti

La lezione «Comprendere il modello di ownership di Rust» è gratuita?

Sì — il testo completo di «Comprendere il modello di ownership di Rust» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 3 lezioni in totale.

Cosa imparerò in «Comprendere il modello di ownership di Rust»?

Comprenda le regole fondamentali dell’ownership e la semantica degli spostamenti, nonché il modo in cui prevengono errori comuni di memoria come il double-free. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Learn Rust Coding?

Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 3.

Quanto tempo richiede la lezione «Comprendere il modello di ownership di Rust»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?

Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Comprendere il modello di ownership di Rust
  2. Spiegazione di riferimenti e borrowing
  3. Lifetime per riferimenti sicuri
← Torna a Learn Rust Coding