Anuncios

Bienvenidos sean a este post, hoy veremos a este operador muy particular.

Anuncios

Este es un operador que se lo denomina propagador de error y trabaja de una forma similar al match, es decir siempre lo ubica al final de una expresion, en caso de no haber ningun error lo opera como siempre pero si encuentra alguno procede a informarlo, para entenderlo vamos a tomar el codigo que vimos en el post anterior y lo modificaremos de la siguiente manera:

main.rs

use std::fs::File;
use std::io;
use std::io::Read;

fn leer_archivo() -> Result<String, io::Error> {
	let mut a = File::open("hola.txt")?;
	let mut s = String::new();
	a.read_to_string(&mut s)?;
	Ok(s)
}

fn main() 
{
	println!("{:?}", leer_archivo());
}
Anuncios
Anuncios

Como pueden ver, basicamente lo que hicimos es sacar los match y los reemplazamos por un signo de interrogacion al final de la apertura del archivo y de la lectura del mismo, esto es asi porque el signo evalua la linea si encuentra que hubo un error va a aprovechar el error que devolvemos con el Result en la funcion de lo contrario sigue como si no hubiera pasado nada, tecnicamente sigue siendo el mismo codigo que el explicado en el post anterior, si tenemos un archivo con informacion al compilarlo y probarlo nos deberia devolver lo siguiente:

tinchicus@dbn001vrt:~/lenguajes/rust/errores$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/errores`
Ok("tinchicus.com es el mejor lugar para aprender.\n")
tinchicus@dbn001vrt:~/lenguajes/rust/errores$
Anuncios

De lo contrario si ocurre alguna falla con el proceso del archivo sucedera lo siguiente:

tinchicus@dbn001vrt:~/lenguajes/rust/errores$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/errores`
Err(Os { code: 13, kind: PermissionDenied, message: "Permission denied" })
tinchicus@dbn001vrt:~/lenguajes/rust/errores$
Anuncios

Esto es ideal para cuando solo manejamos un tipo de error como salida del Result, y ese codigo lo podemos mejorar todavia mas, hagamos la siguiente modificacion al codigo:

main.rs

use std::fs::File;
use std::io;
use std::io::Read;

fn leer_archivo() -> Result<String, io::Error> {
	let mut s = String::new();
	File::open("hola.txt")?.read_to_string(&mut s)?;
	Ok(s)
}

fn main() 
{
	println!("{:?}", leer_archivo());
}
Anuncios
Anuncios

Como dijimos este operador evalua de una forma parecida a match por lo tanto si encuentra un error saldra de bloque y utilizara el tipo de error que utiliza el Result, de lo contrario seguira, en la linea que reemplazamos y unimos las dos acciones de abrir el archivo y leerlo tienen los signos de interrogacion para evaluar sus posibles salidas, si lo compilan y lo prueba deberia funcionar exactamente igual al anterior pero con un codigo mas reducido aunque no tan simple, un ultimo detalle sobre este tipo de operador es que no funcionara por fuera de una funcion que no devuelva un valor de tipo Result, esto es debido a su forma de trabajar, ya que necesita si o si que alguien se encargue de procesar la salida de tipo error que se puede producir dado que el no posee una como tal y tambien como dijimos antes, esto es ideal para manejar un solo tipo de error, aunque puede ser cualquiera, pero si necesitamos manejar mas de un posible tipo de error tendriamos que evaluar el uso de match u otras opciones que hemos visto en los posts anteriores.

Anuncios

En resumen, hoy hemos visto como trabajar el operador de propagacion de error, ?, donde se debe ubicar, como trabaja, como nos permite reducir nuestro codigo, de que tipo depende y como nos permite optimizar el uso de nuestro codigo con las propiedades del OOP, 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