0Pricing
Learn Rust Coding · Lección

Funciones genéricas

Parametrice el comportamiento por tipo

Funciones genéricas es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Learn Rust Coding, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Learn Rust Coding incluye 4 lecciones en total.

¿Por qué usar funciones genéricas?

Las funciones genéricas le permiten escribir una sola función que funciona con muchos tipos, en lugar de copiar el código para cada tipo. Rust reemplaza el tipo de marcador durante la compilación.

Imagine escribir un largest para enteros y otro para caracteres. Los genéricos los convierten en una sola definición sin coste en tiempo de ejecución.

Parámetros de tipo

Una función genérica declara un parámetro de tipo entre corchetes angulares después del nombre. El nombre T es una convención, pero puede utilizar cualquier identificador en CamelCase.

Después, el parámetro puede aparecer en los argumentos y en el tipo de retorno, representando el tipo concreto que utilice quien realiza la llamada.

fn first<T>(pair: (T, T)) -> T {
    pair.0
}

Una función de identidad sencilla

Este programa define un echo genérico que devuelve su argumento sin modificarlo. Se llama una vez con un entero y otra con un segmento de cadena.

El compilador genera una versión concreta independiente para cada tipo que se utiliza realmente.

fn echo<T>(value: T) -> T {
    value
}

fn main() {
    println!("{}", echo(42));
    println!("{}", echo("hi"));
}

Monomorfización

Rust utiliza la monomorfización: durante la compilación produce una copia especializada de la función para cada tipo concreto utilizado. No hay boxing ni despacho virtual.

El resultado es código genérico que se ejecuta con la misma rapidez que el código escrito específicamente para cada tipo.

Los genéricos necesitan restricciones

Dentro de una función genérica solo puede utilizar operaciones compatibles con todos los tipos posibles. Un T sin restricciones no se puede sumar, comparar ni imprimir.

Este código no se puede compilar porque T podría no implementar la comparación. Lo corregiremos a continuación con una restricción de trait.

fn larger<T>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

Añadir una restricción de trait

Para comparar valores, restringimos T con PartialOrd. La restricción garantiza que el tipo admite el operador >.

También añadimos Copy para poder devolver los valores sin problemas de movimiento en tipos simples, como los enteros.

fn larger<T: PartialOrd + Copy>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

Llamar a la función restringida

Ahora la función funciona con cualquier tipo que implemente ambos traits. Tanto los enteros como los números de coma flotante satisfacen PartialOrd + Copy.

El mismo código fuente, monomorfizado en dos versiones, imprime los resultados de cada llamada.

fn larger<T: PartialOrd + Copy>(a: T, b: T) -> T {
    if a > b { a } else { b }
}

fn main() {
    println!("{}", larger(3, 9));
    println!("{}", larger(2.5, 1.0));
}

Varios parámetros de tipo

Una función puede declarar varios parámetros de tipo. Cada uno es independiente, por lo que los dos argumentos pueden tener tipos diferentes.

Aquí, pair acepta cualquier T y cualquier U, y los devuelve como una tupla.

fn pair<T, U>(a: T, b: U) -> (T, U) {
    (a, b)
}

Imprimir valores genéricos

Para imprimir un valor genérico con {}, el tipo debe implementar Display. Añadimos esa restricción para que se pueda pasar cualquier tipo imprimible.

Esta función etiqueta un valor y lo devuelve, demostrando una restricción utilizada exclusivamente para el formato.

use std::fmt::Display;

fn announce<T: Display>(label: &str, value: T) {
    println!("{}: {}", label, value);
}

fn main() {
    announce("count", 7);
    announce("name", "Ada");
}

Sintaxis turbofish

A veces el compilador no puede inferir T únicamente a partir de los argumentos. La sintaxis turbofish ::<Type> le permite especificarlo explícitamente en el punto de la llamada.

Es especialmente habitual con métodos como parse y collect, cuyo tipo de retorno puede resultar ambiguo.

fn main() {
    let n = "42".parse::<i32>().unwrap();
    println!("{}", n + 1);
}

Genéricos sobre referencias

Los parámetros genéricos también funcionan con referencias. Restringir por referencia evita exigir Copy cuando solo necesita leer valores.

Esta función auxiliar al estilo de longest_str toma prestados dos slices y devuelve uno sin asumir su propiedad.

fn pick<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> &'a T {
    if a > b { a } else { b }
}

Comprobación rápida

Compruebe su comprensión de las funciones genéricas en Rust.

Repaso

Las funciones genéricas usan parámetros de tipo entre corchetes angulares para funcionar con muchos tipos sin coste en tiempo de ejecución gracias a la monomorfización.

Las operaciones sobre un tipo genérico requieren límites de traits, como PartialOrd, Copy o Display. Use el turbofish cuando la inferencia no pueda determinar el tipo.

Preguntas frecuentes

¿La lección «Funciones genéricas» es gratis?

Sí — el texto completo de «Funciones genéricas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Learn Rust Coding, actualiza a CoddyKit PRO. El curso de Learn Rust Coding incluye 4 lecciones en total.

¿Qué aprenderé en «Funciones genéricas»?

Parametrice el comportamiento por tipo Practicas Learn Rust Coding con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Learn Rust Coding?

No se requiere experiencia previa. Learn Rust Coding en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Funciones genéricas»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Learn Rust Coding?

Sí. Cada lección de Learn Rust Coding incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Funciones genéricas
  2. Structs y enums genéricos
  3. Límites de traits
  4. Cláusulas where y múltiples límites
← Volver a Learn Rust Coding