Funciones Divergentes en Rust

RustRustBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprendemos sobre funciones divergentes que se marcan con ! en Rust. Las funciones divergentes nunca devuelven y su tipo de retorno es un tipo vacío. Esto es diferente del tipo () que solo tiene un valor posible. Las funciones divergentes pueden ser útiles cuando se requiere convertir a cualquier otro tipo, como en las ramas match. También son el tipo de retorno de las funciones que bucle indefinidamente o terminan el proceso.

Nota: Si el laboratorio no especifica un nombre de archivo, puede usar cualquier nombre de archivo que desee. Por ejemplo, puede usar main.rs, compilar y ejecutarlo con rustc main.rs &&./main.

Funciones divergentes

Las funciones divergentes nunca devuelven. Se marcan con !, que es un tipo vacío.

fn foo() ->! {
    panic!("Esta llamada nunca devuelve.");
}

En contraste con todos los demás tipos, este no se puede instanciar, porque el conjunto de todos los valores posibles que puede tener este tipo está vacío. Tenga en cuenta que es diferente del tipo (), que tiene exactamente un valor posible.

Por ejemplo, esta función devuelve como de costumbre, aunque no hay información en el valor de retorno.

fn some_fn() {
    ()
}

fn main() {
    let _a: () = some_fn();
    println!("Esta función devuelve y puede ver esta línea.");
}

En contraste con esta función, que nunca devolverá el control al llamador.

#![feature(never_type)]

fn main() {
    let x:! = panic!("Esta llamada nunca devuelve.");
    println!("Nunca verá esta línea!");
}

Aunque esto puede parecer un concepto abstracto, de hecho es muy útil y práctico. La principal ventaja de este tipo es que se puede convertir a cualquier otro y, por lo tanto, se puede usar en lugares donde se requiere un tipo exacto, por ejemplo, en las ramas match. Esto nos permite escribir código como este:

fn main() {
    fn sum_odd_numbers(up_to: u32) -> u32 {
        let mut acc = 0;
        for i in 0..up_to {
            // Tenga en cuenta que el tipo de retorno de esta expresión match debe ser u32
            // debido al tipo de la variable "addition".
            let addition: u32 = match i%2 == 1 {
                // La variable "i" es de tipo u32, lo cual está perfectamente bien.
                true => i,
                // Por otro lado, la expresión "continue" no devuelve
                // u32, pero sigue siendo correcta, porque nunca devuelve y, por lo tanto,
                // no viola los requisitos de tipo de la expresión match.
                false => continue,
            };
            acc += addition;
        }
        acc
    }
    println!("Suma de números impares hasta 9 (excluyendo): {}", sum_odd_numbers(9));
}

También es el tipo de retorno de funciones que bucle indefinidamente (por ejemplo, loop {}) como los servidores de red o funciones que terminan el proceso (por ejemplo, exit()).

Resumen

¡Felicitaciones! Has completado el laboratorio de Funciones Divergentes. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.