En aquest tema, explorarem com Rust maneja les situacions d'error crític mitjançant el mecanisme de pànic (panic!) i com es pot desenrotllar (unwind) la pila de crides en resposta a un pànic. També veurem com es pot gestionar el pànic per evitar que el programa es tanqui inesperadament.

Què és un Pànic?

Un pànic en Rust és una situació en la qual el programa troba un error crític del qual no pot recuperar-se. Quan es produeix un pànic, el programa es tanca de manera controlada, desenrotllant la pila de crides i alliberant els recursos adequadament.

Exemple de Pànic

fn main() {
    let v = vec![1, 2, 3];

    // Això causarà un pànic perquè estem intentant accedir a un índex fora de límits
    println!("{}", v[99]);
}

En aquest exemple, intentem accedir a l'element en la posició 99 d'un vector que només té 3 elements. Això causa un pànic perquè l'índex està fora dels límits del vector.

Desenrotllament de la Pila

Quan es produeix un pànic, Rust desenrotlla la pila de crides, alliberant els recursos i cridant els destructors (drop) dels objectes en el camí. Aquest procés assegura que els recursos es gestionen correctament fins i tot en cas d'error.

Configuració del Desenrotllament

Rust permet configurar el comportament del pànic per desenrotllar la pila o per tancar el programa immediatament. Aquesta configuració es pot fer en el fitxer Cargo.toml del projecte:

[profile.release]
panic = 'abort'

Amb aquesta configuració, el programa tancarà immediatament sense desenrotllar la pila en cas de pànic.

Gestió del Pànic

En alguns casos, pot ser desitjable capturar un pànic i gestionar-lo per evitar que el programa es tanqui. Rust proporciona la funció std::panic::catch_unwind per capturar un pànic i continuar l'execució del programa.

Exemple de Captura de Pànic

use std::panic;

fn main() {
    let result = panic::catch_unwind(|| {
        println!("Abans del pànic");
        panic!("Això és un pànic!");
    });

    match result {
        Ok(_) => println!("El codi es va executar sense pànic."),
        Err(_) => println!("Es va capturar un pànic."),
    }

    println!("Després de la captura del pànic");
}

En aquest exemple, el pànic es captura i el programa continua executant-se després de la captura.

Exercicis Pràctics

Exercici 1: Provocar un Pànic

Escriu un programa que provoqui un pànic accedint a un índex fora de límits d'un vector.

Solució

fn main() {
    let v = vec![1, 2, 3];
    println!("{}", v[10]); // Això causarà un pànic
}

Exercici 2: Capturar un Pànic

Modifica el programa anterior per capturar el pànic i imprimir un missatge indicant que s'ha capturat el pànic.

Solució

use std::panic;

fn main() {
    let result = panic::catch_unwind(|| {
        let v = vec![1, 2, 3];
        println!("{}", v[10]); // Això causarà un pànic
    });

    match result {
        Ok(_) => println!("El codi es va executar sense pànic."),
        Err(_) => println!("Es va capturar un pànic."),
    }
}

Errors Comuns i Consells

  • Error Comú: No gestionar adequadament els pànics pot causar que el programa es tanqui inesperadament.

    • Consell: Utilitza panic::catch_unwind per capturar i gestionar els pànics en situacions crítiques.
  • Error Comú: Configurar el pànic per tancar immediatament (abort) pot ser útil per a aplicacions de producció, però pot dificultar el depurament.

    • Consell: Utilitza el desenrotllament de la pila durant el desenvolupament per obtenir més informació sobre els errors.

Conclusió

En aquesta secció, hem après què és un pànic en Rust, com es desenrotlla la pila en cas de pànic i com es pot capturar i gestionar un pànic per evitar que el programa es tanqui inesperadament. Aquests conceptes són crucials per escriure programes robustos i fiables en Rust. En el següent mòdul, explorarem conceptes avançats com les durades de vida, traits i genèrics.

© Copyright 2024. Tots els drets reservats