use std::io;
use std::io::Write;
fn main()
{
let mut s = String::new ();
let v : i32;
let mut h : i32;
const N: i32 = 42;
print! ("Adivina en que número estoy pensando ? ");
let _= io::stdout().flush();
io::stdin().read_line (&mut s).unwrap();
v = s.trim().parse().unwrap();
if v < 0 {
println! ("Solo Número Positivos!!");
return ;
}
if v == N { println! ("Bien Hecho!!!");}
else {
println! ("Sigue Probando");
println! ("El número es {}", if v < n {"MAYOR"} else {"MENOR"});
h = v - N;
h *= if v > N {1} else {-1};
print!("PISTA :");
if h < 5 { println!("TE QUEMAS!!!!");}
else if h < 10 { println! ("CALIENTE");}
else if h < 15 { println! ("TEMPLADO");}
else { println!("FRIO");}
}
}Rust no nos ofrece una gran cantidad de opciones para escribir
expresiones condicionales en los programas. Dispone de bloques
if-else ala C y, si bien no dispone de un operador
ternario, sin embargo puede tratar los bloques if como expresiones y asignar su resultado a variables.
En el ejemplo, podemos ver como usamos está capacidad para determinar
el valor absoluto de la expresión que utilizamos para generar la pista.
Como podéis ver, la posibilidad de utilizar if como una
expresión hace que podamos usar esta construcción como el operador
ternario ?: de lenguajes como C y Java, si bien se trata de
una construcción mucho más potente.
Otra forma de obtener el valor absoluto podría ser:
h = if (v > n) {v - n} else {n-v};Utilizando esta expresión no necesitamos que nuestra variable
h sea mutable, lo cual es una de las capacidades del
lenguaje para hacer que el código sea más robusto.
SABÍAS QUE
En Rust todas las variables son inmutables. Eso significa que una vez que se les ha asignado un valor, ese valor no puede cambiarse. Si necesitamos poder modificar el valor de una variable varias veces, podemos declararla como mutable utilizando la palabra clave
mut. También podemos ensombrecerla (Shadowing), simplemente declarando una nueva variable con el mismo nombre. Eso lo conseguimos utilizando la palabra claveletde nuevo. Eso realmente genera una nueva variable con el mismo nombre de tal forma que la variable original no se modifica, pero podemos asignar nuevos valores a esta copia a partir de ese punto en nuestro programa. Por ejemplo el programalet v = 10; println! ("V tiene Valor ()", v); { let v = 20; println! ("V tiene Valor ()", v); } println! ("V tiene Valor ()", v);En programa imprimirá los valores, 10, 20 y 10 nuevamente. En el bloque intermedio (delimitado por las llaves), la variable
ves una variable totalmente distinta con el mismo nombre que la variablevdel bloque exterior, sin embargo, en el bloque interior referenciamos la copia local. Al salir del bloque de código,vvuelve a ser la variable original, ya que lavlocal deja de existir fuera del bloque de código en el que se declaró.
Rust ofrece una instrucción similar a switch utilizando
la palabra clave match. match funciona
prácticagmente igual que switch, pero, al igual que con
otros lenguajes nos permite algunas ventajas como especificar varios
casos a la vez y comparar otros tipos (siempre que los casos se definan
usando literales). El caso _ se utiliza para indicar el
caso por defecto. El siguiente ejemplo ilustra la sintaxis de este
comando incluyendo varios ejemplos de la sintaxis.
let value = 10;
match value {
1 => println!("Uno"),
2 | 3 | 4 | 5 => println!("Mayor que 1 y menor que 6"),
20..=30 => println!("Entre 20 y 30"),
_ => println!("valor por defecto"),
};match también se puede utilizar como una expresión,
asigando el valor que retorne el caso activo a alguna variable.
let bo = true;
let bstr = match bo {
true => "True!",
false => "False",
};
println!("bo is {}", bstr);O si lo preferís:
println! ("bo is {}", match bo {
true => "True!",
false => "False",
});Como podéis comprobar en los ejemplos de arriba, Rust suporta tipos
booleanos con valores true y
false.
SOY NOVATO
Rust no ofrece una forma directa de leer un número entero de la entrada estándard. Para hacer eso primero leemos una línea de texto (
read_line) a la que le quitamos el retorno de carro (trim) y luego la convertimos en un número entero usando (parse).El método
parsees muy general y es una de las raras excepciones que utiliza la sintaxis conocida como Turbo Fish::<>la cual permite forzar el tipo al que queremos convertir. En nuestro ejemplo podríamos haber usadov = s.trim().parse::<i32>().unwrap();para forzar la conversión a uni32Métodos como
read_lineoparsepueden producir errores. Rust, en esos casos devuelve un tipo especial llamadoResultel cual puede contener o el resultado de la operación o un error que deberíamos procesar. El métodounwrap()lo que hace es devolvernos el valor si el resultado es correcto o abortar el programa en caso de error. Podemos utilizar el métodoexpectsi queremos obtener un mensaje específico al abortar el programa (panicking en Rust verborrea).La forma de procesar un método que devuelve un tipo
Resultcomo por ejemploparsees utilizandomatch. Este sería un ejemplo:v = match string.parse::<i32>() { Ok(n) => n, Err(_) => { println!("No puedo leer un número"); 0 }, };Este código asignará a
vel valor retornado porparsesi no hubo errores, o mostrará el mensaje de error y retornara0en caso de que no se pudiera convertir la cadena a entero. El métodounwraplo podemos usar cuando no queremos procesar los errores y está bien si el programa termina con un error en caso de que una determinada función (parseen nuestro ejemplo) devuelva un error.
Rust permite definir constantes utilizando la palabra clave
const. Como curiosidad, el compilador emitirá un
warning si la constante no comienza por mayúsculas.
Resumen
- Soporta
if ... [else if] ...[else] ... - No tiene forma reducida de
if, peroifes una expresión en el lenguaje - No tiene operador terciario pero
ifes una expresión en el lenguaje - Soporta booleanos:
boolcon valorestrue/false - Soporta
switchcon palabra clavematch - Soporta constantes nativamente
(
const CONSTANTE: type = val)
■
