Saltar al contenido principal
eLearner.app
Módulo 5 · Lección 1 de 29/14 en el curso~12 min
Lecciones del módulo (1/2)

Genéricos y funciones

Los generics (tipos genéricos) permiten escribir código flexible y reutilizable, evitando la duplicación de lógica para diferentes tipos de datos. En lugar de definir múltiples funciones o estructuras para tipos diferentes (como i32, f64 o String), podemos usar un parámetro de tipo genérico, indicado convencionalmente con la letra T.

El compilador de Rust gestiona los generics mediante un proceso llamado monomorfización: durante la compilación, el compilador genera una copia del código genérico para cada tipo concreto con el que se utiliza realmente. De esta manera, no hay sobrecarga de rendimiento en tiempo de ejecución.


Funciones Genéricas

Para definir una función genérica, colocamos el parámetro de tipo <T> inmediatamente después del nombre de la función y antes de la lista de parámetros:

Code
fn print_value<T: std::fmt::Debug>(value: T) {
    println!("Valore: {:?}", value);
}

En las funciones genéricas, podemos usar el tipo genérico T tanto para los tipos de los argumentos como para el tipo de retorno:

Code
fn identity<T>(value: T) -> T {
    value
}

Estructuras Genéricas

También podemos utilizar los parámetros de tipo genérico dentro de las estructuras de datos (struct) para definir campos flexibles:

Code
struct KeyValuePair<K, V> {
    key: K,
    value: V,
}

fn main() {
    let pair = KeyValuePair {
        key: String::from("eta"),
        value: 30,
    };
}

En el bloque impl para una struct genérica, debemos declarar el parámetro de tipo <T> inmediatamente después de la palabra clave impl para indicar que estamos implementando métodos sobre una estructura genérica:

Code
struct Container<T> {
    value: T,
}

impl<T> Container<T> {
    fn new(value: T) -> Self {
        Container { value }
    }

    fn value(&self) -> &T {
        &self.value
    }
}

Pruébalo tú

Ejercicio 1: La estructura Point

Ejercicio#rust.m5.l1.e1
Intentos: 0Cargando...

Define una estructura genérica llamada Point<T> con dos campos: x de tipo T y y de tipo T. En el main, instancia una variable point que contenga un Point con valores x igual a 5 y y igual a 10 (enteros), luego imprime en pantalla el valor de point.x.

Cargando editor...
Mostrar pista

Declara la struct usando `struct Point<T> { x: T, y: T }`. Instánciala en el main y usa `point.x` para imprimirla.

Solución disponible después de 3 intentos

Ejercicio 2: Inversión de una Tupla con swap

Ejercicio#rust.m5.l1.e2
Intentos: 0Cargando...

Escribe una función genérica llamada swap<T> que acepte como entrada una tupla de dos elementos (T, T) y devuelva una nueva tupla (T, T) con los elementos invertidos de posición. En el main, llama a la función con la tupla (1, 2) e imprime el resultado.

Cargando editor...
Mostrar pista

La firma de la función debe ser `fn swap<T>(pair: (T, T)) -> (T, T)`. Devuelve la tupla invertida con `(pair.1, pair.0)`.

Solución disponible después de 3 intentos

Ejercicio 3: La estructura Container

Ejercicio#rust.m5.l1.e3
Intentos: 0Cargando...

Define una struct genérica Container<T> que contenga un campo value de tipo T. Implementa un bloque impl genérico para definir un método new que acepte un valor de tipo T y devuelva una instancia de Container<T>.

Cargando editor...
Mostrar pista

Usa `impl<T> Container<T>`para implementar el método asociado`fn new(value: T) -> Self { Container { value } }`.

Solución disponible después de 3 intentos