Imprimiendo '¡Hola, mundo!'
Puedes ver este capítulo en YouTube en inglés: Video 1, Video 2
Cuando creas un nuevo programa Rust, siempre contiene este código:
fn main() { println!("Hello, world!"); }
fn
significa función.main
es el nombre de la función que inicia el programa.()
significa que en este caso no se le pasan variables a esta función.{}
es un bloque de código. Es donde se encuentra el código.println!
es una macro, que es como una función que sirve para escribir código por ti. Las macros siempre tienen un!
al final de su nombre. Por ahora, recuerda que!
significa que es una macro.
Para aprender lo que hace ;
, crearemos otra función. Primero, en main
imprimiremos el número 81.
1 N.T.: aprovechamos para cambiar el saludo a español. En Rust, cuando se utiliza la aplicación cargo
para crear un programa, siempre se incorpora el código de main
con "Hello, world!" de forma automática.
fn main() { println!("¡Hola, mundo número {}!", 8); }
Las {}
dentro de println!
indican a Rust que "ponga la variable en este lugar". Este código imprime ¡Hola, mundo número 8!
.
Podemos poner más cosas ampliando lo anterior.
fn main() { println!("¡Hola, mundos número {} y {}!", 8, 9); }
El codigo anterior imprime ¡Hola, mundos número 8 y 9!
.
Ahora vamos a crear una función.
fn numero() -> i32 { 8 } fn main() { println!("¡Hola, mundo número {}!", numero()); }
El código anterior también imprime ¡Hola, mundo número 8!
. Cuando Rust encuentra numero()
entiende que es una función. Esta función:
- No toma ningún parámetro (porque tiene una llamada con
()
). - Devuelve un
i32
. El símbolo de flecha->
muestra el tipo que devuelve la función. - La función en sí misma solo contiene un
8
. Al no terminar en;
este valor es el que devuelve al terminar de ejecutarse. Si tuviera un;
detrás, la función no devolvería nada (devolvería un()
). Rust no compilaría si contuviera un;
al final ya que se ha indicado que (tras la flecha) debe devolver un valor de tipoi32
y con el;
se devuelve()
que no es de tipoi32
.
fn numero() -> i32 { 8; } fn main() { println!("¡Hola, mundo número {}!", numero()); }
error[E0308]: mismatched types
--> src/main.rs:1:16
|
1 | fn numero() -> i32 {
| ------ ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
2 | 8;
| - help: consider removing this semicolon
Esto significa que "me dijiste que numero()
devuelve un i32
, pero añadiste un ;
por lo que esta función no devuelve nada". Así que el compilador sugiere que se elimine el punto y coma.
También se puede escribir lo siguiente return 8;
, pero en Rust lo normal es simplemente eliminar el ;
para ejecutar el return
.
Cuando se quiere pasar variables a una función, se deben poner dentro de ()
. Hay que darles un nombre e indicar su tipo.
// Entran a la función dos i32s. Se llaman num_uno y num_dos fn multiplicar(num_uno: i32, num_dos: i32) { let resultado = num_uno * num_dos; println!("{} por {} es {}", num_uno, num_dos, resultado); } fn main() { multiplicar(8, 9); // Pasamos unos números directamente let algun_numero = 10; // o podemos declarar dos variables let algun_otro_numero = 2; multiplicar(algun_numero, algun_otro_numero); // y pasarlos a la función }
También se puede devolver un i32
. Basta con poner la variable resultado
como la última de la función sin ;
al final.
fn multiplicar(num_uno: i32, num_dos: i32) -> i32 { let resultado = num_uno * num_dos; println!("{} por {} es {}", num_uno, num_dos, resultado); resultado // este es el valor i32 que se retorna } fn main() { // multiplicar() imprime el resultado y lo devuelve, // lo que permite asignarlo a resultado_mult let resultado_mult = multiplicar(8, 9); }
La declaración de variables y los bloques de código
Se usa let
para declarar una variable (para decirle a Rust que construya una variable).
fn main() { let mi_numero = 8; println!("¡Hola, mundo número {}!", mi_numero); }
Las variables existen dentro de un bloque de código {}
. En el siguiente ejemplo mi_numero
desaparece antes de llamar a println!
porque se encuentra dentro de su propio código.
fn main() { { let mi_numero = 8; // mi_numero se crea aquí // mi_numero se extingue aquí } println!("¡Hola, mundo número {}!", mi_numero);// ⚠️ mi_numero no existe y // println!() no lo puede encontrar }
Se puede usar un bloque de código para devolver un valor, como en el siguiente código.
fn main() { let mi_numero = { let segundo_num = 8; segundo_num + 9 // sin punto y coma, por lo que el // bloque de código devuelve 8 + 9 = 17 }; println!("¡Hola, mundo número {}!", mi_numero); }
Si se añadiera un punto y coma en la sentencia final del bloque, devolvería ()
(nada).
fn main() { let mi_numero = { let segundo_num = 8; // declara el segundo número segundo_num + 9; // suma 9 con el segundo número // pero no se devuelve // segundo_num desaparece aquí }; println!("¡Hola, mundo número {:?}!", mi_numero); // mi_numero es () }
Si has observado bien, hemos cambiado {}
por {:?}
. El motivo se verá en el siguiente capítulo.