Los genéricos en Rust permiten escribir código flexible y reutilizable. En lugar de definir funciones, structs o enums para cada tipo de dato específico, puedes usar genéricos para trabajar con cualquier tipo de dato. Este enfoque no solo reduce la duplicación de código, sino que también mejora la legibilidad y el mantenimiento del código.
Conceptos Clave
- Definición de Genéricos: Los genéricos se definen utilizando el símbolo
<T>, dondeTes un marcador de posición para un tipo de dato. - Funciones Genéricas: Permiten que las funciones trabajen con diferentes tipos de datos sin necesidad de definir múltiples versiones de la misma función.
- Structs Genéricos: Permiten que las estructuras almacenen diferentes tipos de datos.
- Enums Genéricos: Permiten que los enums manejen diferentes tipos de datos en sus variantes.
Funciones Genéricas
Ejemplo Básico
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}Explicación
fn largest<T: PartialOrd>(list: &[T]) -> &T: Define una función genéricalargestque acepta una referencia a un slice de cualquier tipoTque implemente el traitPartialOrd(necesario para comparar elementos).let mut largest = &list[0];: Inicializalargestcon la referencia al primer elemento del slice.for item in list: Itera sobre cada elemento en el slice.if item > largest: Compara el elemento actual con el más grande encontrado hasta ahora.largest = item;: Actualizalargestsi se encuentra un elemento mayor.
Ejercicio
Escribe una función genérica smallest que encuentre el elemento más pequeño en un slice.
Solución
fn smallest<T: PartialOrd>(list: &[T]) -> &T {
let mut smallest = &list[0];
for item in list {
if item < smallest {
smallest = item;
}
}
smallest
}Structs Genéricos
Ejemplo Básico
Explicación
struct Point<T>: Define una estructura genéricaPointcon dos camposxyydel mismo tipoT.impl<T> Point<T>: Implementa métodos para la estructuraPoint.fn new(x: T, y: T) -> Self: Método constructor que crea una nueva instancia dePoint.
Ejercicio
Define una estructura genérica Rectangle con campos width y height, y un método area que calcule el área del rectángulo.
struct Rectangle<T> {
width: T,
height: T,
}
impl<T> Rectangle<T> {
fn area(&self) -> T {
// Tu código aquí
}
}Solución
struct Rectangle<T> {
width: T,
height: T,
}
impl<T: std::ops::Mul<Output = T> + Copy> Rectangle<T> {
fn area(&self) -> T {
self.width * self.height
}
}Enums Genéricos
Ejemplo Básico
Explicación
enum Option<T>: Define un enum genéricoOptioncon dos variantes:Someque contiene un valor de tipoTyNoneque no contiene ningún valor.
Ejercicio
Define un enum genérico Result con dos variantes: Ok que contiene un valor de tipo T y Err que contiene un valor de tipo E.
Solución
Conclusión
Los genéricos en Rust son una herramienta poderosa que permite escribir código más flexible y reutilizable. Al entender cómo definir y utilizar funciones, structs y enums genéricos, puedes crear programas más eficientes y fáciles de mantener. En el siguiente módulo, exploraremos la concurrencia en Rust, que te permitirá escribir programas que aprovechen al máximo los procesadores multinúcleo.
Curso de Programación en Rust
Módulo 1: Introducción a Rust
- ¿Qué es Rust?
- Configuración del Entorno de Rust
- Programa "Hola, Mundo!"
- Sintaxis y Estructura Básica
