Anuncios

Bienvenidos sean a este post, hoy veremos dos temas muy particulares.

Anuncios

El primero sera como llegamos a la construccion if let que vimos en el post anterior y el otro sera las coincidencias o matching, les suena el nombre?, para comenzar vamos a analizar el siguiente bloque de ejemplo:

fn prueba(x: i32) -> String 
{ 
    if x == 1 
    {   
        return "uno".to_owned(); 
    } 
    else if x == 2 
    { 
        return "dos".to_owned(); 
    } 
    else if x == 3 
    { 
        return "tres".to_owned(); 
    } 
    return "no encontrado".to_owned(); 
} 
Anuncios
Anuncios

Esta funcion es simple, la cual recibe un valor de tipo int y devuelve un valor de tipo string, en el bloque tenemos una serie de condicionales donde verificamos tres posibles valores, si se cumple cualquiera de las tres condiciones devolvera un valor de tipo string (gracias al to_owned) saliendo de la funcion, por ultimo si no se cumple ninguna de las condiciones devuelve una notificacion de que no se encontro, esta es completamente operativa pero podemos mejorarla de la siguiente manera:

fn prueba(x: i32) -> String 
{ 
	let t = match x
	{
		1 => t = "uno".to_owned(),
		2 => t = "dos".to_owned(),
		3 => t = "tres".to_owned(),
		_ => t = "no encontrado".to_owned()
	}
	return t;
} 
Anuncios

Para este caso implementamos a match, del cual hablamos en este post, donde quitamos todos los condicionales, lo reemplazamos con el match para los distintos valores que podemos evaluar y los posibles valores lo almacenaremos en una variable llamado t al cual lo devolvemos, pero esto lo podemos simplificar mas aun:

fn prueba(x: i32) -> String 
{ 
	match x
	{
		1 => "uno".to_owned(),
		2 => "dos".to_owned(),
		3 => "tres".to_owned(),
		_ => "no encontrado".to_owned()
	}
} 
Anuncios

Recuerdan que en este post mencionamos que si en un bloque no usabamos el punto y coma este devolvia automaticamente el valor, con esto tenemos una base pasemos a ver como se pueden usar enum con match.

Anuncios

De enum hablamos en el post anterior y vimos como manejarlo por medio de condicionales if y uno bastante particular como era if let, con esto comentado pasemos a ver el siguiente codigo:

enum numerado
{
	TipoTuple(f32, i64, String),
	TipoStruct{ var1: i32, var2: f32},
	TipoNuevoTuple(f32),
	variable
}

fn tipo_tuple(v: f32, c: i64, t: String) { // algo de codigo }
fn tipo_struct(v1: i32, v2: f32) { // algo de codigo }
fn tipo_nuevo_tuple(n: f32) { // algo de codigo }
fn procesar_var() { // algo de codigo }

fn coincidir(e: numerado)
{
	match e
	{
		numerado::variable => procesar_var(),
		numerado::TipoTuple(f,i,s) => tipo_tuple(f, i, s),
		numerado::TipoStruct(v1,v2) => tipo_struct(v1,v2),
		numerado::TipoNuevoTuple(i) => tipo_nuevo_tuple(i)
	}
}
Anuncios

El enum es el que utilizamos en el post cuando hablamos de este tipo, donde basicamente tendremos varios de los otros tipos que disponemos del lenguaje (tuple, struct, variable), despues tendremos cuatro funciones para manipular a los tipos del enum con el codigo que necesitemos, por ultimo tenemos la funcion que mas nos interesa:

fn coincidir(e: numerado)
{
	match e
	{
		numerado::variable => procesar_var(),
		numerado::TipoTuple(f,i,s) => tipo_tuple(f, i, s),
		numerado::TipoStruct(v1,v2) => tipo_struct(v1,v2),
		numerado::TipoNuevoTuple(i) => tipo_nuevo_tuple(i)
	}
}
Anuncios
Anuncios

Observen que la funcion recibe un valor del tipo del enum, luego tenemos un match donde evalua este atributo y para verificar si alguno de los valores pasados coincide con alguno de los tipos que tiene este enum, para ello pasamos el enum seguido del tipo con la nomenclatura para poder encontrarlo y en caso de coincidencia llamamos a la funcion que estaria involucrada, en este caso no fue necesario el guion bajo porque evaluamos todos los posibles valores pero si sacaramos alguno podriamos utilizarlo para ese tipo, pero tambien podemos usarlo con struct, para ello vamos a usar el siguiente codigo:

struct Prueba
{
	respuesta: i32,
	respuesta_real: i32,
	puntaje: i32,
}

fn coincidir(p: Prueba)
{
	match p
	{
		Prueba(respuesta: Pregunta::MiRespuesta, respuesta_real:
				Pregunta::RespuestaReal, ..) => {...}
	}
}
Anuncios
Anuncios

Primero tenemos un strucct que almacena tres datos, uno para la respuesta que enviemos, otro para la respuesta real y uno final para el puntaje de la pregunta, luego tenemos una funcion para hacer la coincidencia, en este caso al igual que el enum como tipo de argumento pasamos al struct, luego en el match utilizamos el argumento y en esta crearemos un objeto de este struct, observen que pasamos dos parametros del struct con valores de otra clase pero no pasamos a puntaje, en su lugar usamos los dos puntos (..), este operador nos permite ignorar todos los parametros de aqui en adelante, pero para este caso solo omite puntaje, aunque a este bloque lo podemos convertir de la siguiente manera:

	match p
	{
		Prueba(respuesta: Pregunta::MiRespuesta, respuesta_real:
				Pregunta::RespuestaReal, puntaje:_) => {...}
	}
Anuncios

En este caso como omitimos uno solo podemos usar el guion bajo para que no importe el valor lo pase de largo tal como hicimos anteriormente pero recuerden que el anterior omite mas campos.

Anuncios

Cuando hablamos de match en este post dijimos que este metodo no reemplaza al condicional if sino que lo complementa, analicemos el siguiente caso:

fn prueba(p: i32)
{
	match p
	{
		1 | 2 if p !=1 => println!("Este no es uno"),
		1 | 2 if p !=2 => println!("Este no es dos")
	}
}
Anuncios

En este caso simplemennte agregamos un condicional if despues de los patrones donde pasaremos la condicion y en caso de cumplirse ejecutara la funcion que asociemos, por ultimo podemos usar a match con distintos tipos, veamos un codigo de ejemplo:

struct Estructura
{
	a: i32,
	b: i32
}

fn funcion()
{
	let miestructura = Estructura(a: 1, b: 2);
	match miestructura
	{
		Estructura(a, b) => println!("Coinciden estructuras"),
		_ => println!("No coinciden")
	}
}
Anuncios

En este caso volvemos a usar a struct porque es el mas simple de examinar, este es uno simple con dos variables, luego tenemos una funcion donde crearemos un objeto de este struct con dos valores iniciales, luego usaremos un match donde pasaremos el nombre del struct con dos valores, en caso de coincidencia mostraremos un mensaje de lo contrario mostraremos otro.

Anuncios

A esta altura se preguntaran cuando hablaremos sobre if let, bueno este es el momento porque basicamente if let no deja de ser un match (o por lo menos trabaja de manera igual), especialmente si lo observamos con el ultimo caso y lo comparamos con el visto en el post anterior, por ejemplo veamos este match:

match x
{
	1 => println!("uno"),
	_ => println!("no encontrado")
}
Anuncios

Este mismo codigo lo podemos convertir de la siguiente manera:

if let 1 = x
{
	println!("uno");
}
else
{
	println!("no encontrado");
}
Anuncios

Como pueden ver puede que no sea mas practico que match pero en determinadas circunstancias puede ser mas practico.

Anuncios

En resumen, hoy hemos visto como podemos unir a match con enum, o con struct, algunas particularidades que podemos tener para manejar la informacion de nuestros codigos, despues vimos como if let es muy similar a match y el motivo que tuvimos que explicar todo antes de mostrarlo, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50