Le funzioni sono una parte essenziale di qualsiasi linguaggio di programmazione, e Rust non fa eccezione. Permettono di suddividere il codice in unità logiche, migliorandone la leggibilità e la riusabilità. Inoltre, Rust offre strumenti avanzati come i moduli per organizzare grandi progetti e una gestione chiara dello scope per controllare la visibilità delle variabili e delle funzioni. In questo articolo, esploreremo come definire e usare funzioni, gestire parametri e valori di ritorno, comprendere lo scope e strutturare il codice con i moduli.
Definizione e Uso delle Funzioni
In Rust, le funzioni si definiscono usando la parola chiave fn, seguita dal nome della funzione, una lista di parametri opzionali racchiusi tra parentesi tonde, e un corpo racchiuso tra parentesi graffe.
Esempio: Funzione Base
fn saluta() {
println!("Ciao, benvenuto in Rust!");
}
fn main() {
saluta(); // Chiamata della funzione
}
In questo esempio, abbiamo definito una funzione semplice chiamata saluta e l’abbiamo richiamata all’interno della funzione principale main.
Parametri e Valori di Ritorno
Parametri
Le funzioni possono accettare parametri per rendere il loro comportamento più flessibile. Ogni parametro deve essere accompagnato dal tipo.
fn saluta_persona(nome: &str) {
println!("Ciao, {}!", nome);
}
fn main() {
saluta_persona("Alice");
}
Valori di Ritorno
Le funzioni possono restituire valori utilizzando il tipo di ritorno, specificato dopo una freccia ->.
fn somma(a: i32, b: i32) -> i32 {
a + b // L'ultima espressione è il valore restituito
}
fn main() {
let risultato = somma(4, 6);
println!("La somma è: {}", risultato);
}
Se non ci sono valori da restituire, il tipo di ritorno è () (unit), che può essere omesso.
Esempio Completo
Ecco una funzione con parametri e un valore di ritorno, utilizzata per calcolare l’area di un rettangolo:
fn calcola_area(lunghezza: f32, larghezza: f32) -> f32 {
lunghezza * larghezza
}
fn main() {
let area = calcola_area(5.0, 3.0);
println!("L'area del rettangolo è: {}", area);
}
Scope in Rust
In Rust, lo scope (ambito) di una variabile o funzione definisce dove può essere usata nel codice. Comprendere come funziona lo scope è essenziale per scrivere codice sicuro e ben organizzato.
Scope delle Variabili
Le variabili in Rust sono visibili solo all’interno del blocco in cui vengono dichiarate. Ad esempio:
fn main() {
let x = 10;
{
let y = 5; // y è visibile solo all'interno di questo blocco
println!("x: {}, y: {}", x, y);
}
// println!("y: {}", y); // Errore: y non è visibile qui
}
Quando una variabile esce dallo scope, la sua memoria viene liberata automaticamente grazie al sistema di ownership di Rust.
Scope e Funzioni
Le funzioni possono accedere solo alle variabili che vengono passate come argomenti o dichiarate all’interno dello scope della funzione stessa.
fn stampa_valore(valore: i32) {
println!("Il valore è: {}", valore);
}
fn main() {
let numero = 42;
stampa_valore(numero);
}
Creare Moduli per Organizzare il Codice
Man mano che il tuo progetto cresce, avrai bisogno di organizzare il codice. I moduli in Rust ti aiutano a strutturare le tue funzioni e altre definizioni in unità logiche.
Definizione di un Modulo
Un modulo è una raccolta di funzioni e altri oggetti correlati.
mod calcoli {
pub fn somma(a: i32, b: i32) -> i32 {
a + b
}
}
fn main() {
let risultato = calcoli::somma(10, 20);
println!("La somma è: {}", risultato);
}
- La parola chiave
pubrende la funzione accessibile dall’esterno del modulo. - Le funzioni senza
pubsono private al modulo.
Moduli in File Separati
Per progetti più grandi, puoi separare i moduli in file diversi:
-
File
main.rs:mod calcoli; fn main() { let risultato = calcoli::somma(10, 5); println!("Risultato: {}", risultato); } - File
calcoli.rs:
pub fn somma(a: i32, b: i32) -> i32 { a + b }
Esercizi Pratici
- Esercizio 1: Crea una funzione chiamata
moltiplicache accetta due numeri e restituisce il prodotto. - Esercizio 2: Organizza due funzioni (
somma,sottrai) in un modulo chiamatooperazioni. - Esercizio 3: Scrivi un programma che utilizza una funzione in un modulo separato per calcolare l’area di un cerchio.
- Esercizio 4: Prova a creare una variabile all’interno di un blocco e vedere come cambia la visibilità usando lo scope.
Conclusione
Le funzioni e i moduli in Rust sono strumenti potenti per creare codice leggibile, riutilizzabile e ben strutturato. Apprendere i concetti di scope e modularità ti permette di scrivere programmi ben organizzati e facilmente scalabili. Nella prossima lezione, esploreremo concetti come Ownership, Borrowing e Lifetimes, che aggiungono ancora più flessibilità al tuo codice.
Lascia un commento