Funciones en Rust
Una función es un bloque de código con nombre que puedes reutilizar. En lugar de escribir los mismos pasos una y otra vez, los pones una sola vez en una función y la llamas cada vez que la necesites. De hecho, ya has usado una: main.
Definir y llamar una función
Sección titulada «Definir y llamar una función»Defines una función con fn y la llamas escribiendo su nombre seguido de ():
fn greet() { println!("¡Hola desde una función!");}
fn main() { greet(); // la llamamos greet(); // y la llamamos otra vez}Salida:
¡Hola desde una función!¡Hola desde una función!Parámetros: darle datos a una función
Sección titulada «Parámetros: darle datos a una función»Las funciones se vuelven útiles cuando les pasas datos con los que trabajar. Esos datos de entrada se llaman parámetros. En Rust tienes que escribir el tipo de cada parámetro:
fn greet(name: &str) { println!("¡Hola, {name}!");}
fn main() { greet("Alice"); greet("Bob");}Salida:
¡Hola, Alice!¡Hola, Bob!Puedes tener todos los parámetros que necesites, separados por comas:
fn describe(name: &str, age: u32) { println!("{name} tiene {age} años");}
fn main() { describe("Ferris", 10);}Salida:
Ferris tiene 10 añosLos valores que pasas se asignan a los parámetros por posición: el primer valor va a name y el segundo a age. Si los pasas en el orden equivocado, como describe(10, "Ferris"), es un error de compilación, porque los tipos no coinciden.
Devolver un valor
Sección titulada «Devolver un valor»Una función puede entregarle un valor de vuelta a quien la llamó. El tipo de retorno se declara después de una flecha ->:
fn add(a: i32, b: i32) -> i32 { a + b}
fn main() { let sum = add(3, 4); println!("3 + 4 = {sum}");}Salida:
3 + 4 = 7La regla del punto y coma (¡importante!)
Sección titulada «La regla del punto y coma (¡importante!)»Fíjate en que a + b en el ejemplo anterior no lleva punto y coma. Esta es una idea clave en Rust:
- Una expresión sin punto y coma es el valor que se devuelve.
- Si le agregas un punto y coma, se convierte en una instrucción que no devuelve nada.
Así que esto falla:
fn add(a: i32, b: i32) -> i32 { a + b; // ❌ el punto y coma significa "no devuelvo nada", pero prometimos un i32}El compilador se quejará de que la función debería devolver un i32 y no lo hace. La solución es simplemente quitar el punto y coma de la última línea.
Todo junto
Sección titulada «Todo junto»fn square(n: i32) -> i32 { n * n}
fn main() { let result = square(5); println!("5 al cuadrado es {result}");}Salida:
5 al cuadrado es 25Práctica
Sección titulada «Práctica»1. De Celsius a Fahrenheit
Sección titulada «1. De Celsius a Fahrenheit»Escribe una función to_fahrenheit que reciba una temperatura en grados Celsius como f64 y la devuelva en Fahrenheit. La fórmula es c * 9.0 / 5.0 + 32.0. Llámala con 0, 100 y 37 grados. Pista: la firma es fn to_fahrenheit(c: f64) -> f64, y el cuerpo es una sola expresión sin punto y coma.
Ver solución
fn to_fahrenheit(c: f64) -> f64 { c * 9.0 / 5.0 + 32.0}
fn main() { println!("0°C son {}°F", to_fahrenheit(0.0)); println!("100°C son {}°F", to_fahrenheit(100.0)); println!("37°C son {}°F", to_fahrenheit(37.0));}Salida:
0°C son 32°F100°C son 212°F37°C son 98.6°FFíjate en que pasamos 0.0, no 0. El parámetro es un f64, y Rust no convierte un entero en decimal por su cuenta. Cuando un f64 no tiene parte decimal, {} lo imprime sin el .0; por eso ves 32 y no 32.0.
2. El mayor de tres
Sección titulada «2. El mayor de tres»Escribe una función largest(a: i32, b: i32, c: i32) -> i32 que devuelva el mayor de sus tres números. Pruébala con (3, 9, 4) y (-2, -8, -5). Pista: en Rust, if es una expresión (mira If…Else), así que una cadena if / else if / else puede ser la última línea de la función.
Ver solución
fn largest(a: i32, b: i32, c: i32) -> i32 { if a >= b && a >= c { a } else if b >= c { b } else { c }}
fn main() { println!("{}", largest(3, 9, 4)); println!("{}", largest(-2, -8, -5));}Salida:
9-2Ninguna de las ramas termina en punto y coma. Cada una es una expresión, la cadena if completa devuelve una de ellas, y ese es el valor de retorno. Usar >= en lugar de > garantiza que, si hay empate, también se devuelva un valor.
Resumen
Sección titulada «Resumen»- Defines funciones con
fny las llamas connombre(). - Los parámetros son los datos de entrada; cada uno necesita un tipo:
fn greet(name: &str). - Declaras el tipo de retorno con
-> Tipo. - La última expresión sin punto y coma es el valor que se devuelve.
return valor;también funciona, pero normalmente se usa solo para salir antes de tiempo.
Comprueba lo que aprendiste
Sección titulada «Comprueba lo que aprendiste»Comprueba lo aprendido
1. En Rust, ¿tienes que escribir el tipo de cada parámetro de una función?
2. ¿Cómo declaras el tipo de retorno de una función?
3. ¿Por qué a + b (sin punto y coma) al final de una función se convierte en su valor de retorno?
4. ¿Importa si defines una función antes o después del lugar donde se llama (por ejemplo, antes o después de main)?
Puntuación: 0 / 4
Para leer más
Sección titulada «Para leer más»- Funciones — El libro de Rust (en inglés): el capítulo oficial sobre parámetros, valores de retorno e instrucciones frente a expresiones.
- Instrucciones y expresiones — El libro de Rust (en inglés): una mirada más de cerca a la idea que hay detrás de la regla del punto y coma.
- Funciones — Rust by Example (en inglés): ejemplos ejecutables, incluidos
returnanticipados y funciones que no devuelven nada. - Funciones — The Rust Reference (en inglés): las reglas exactas de cómo se definen las funciones, para cuando quieras la letra pequeña.
- La palabra clave
fn— documentación de la biblioteca estándar (en inglés): un resumen breve de la sintaxis de las funciones, con ejemplos.