Anuncios

Bienvenidos sean a este post, hoy hablaremos sobre un atributo particular.

Anuncios
Anuncios

Cuando hablamos del metodo unsafe en este post comentamos sobre la declaracion de un atributo al comienzo de un codigo por medio del numeral (#) y entre corchetes el atributo, en ese caso usamos a feature pero derive no deja de ser otro que nos permite implementar de manera rapida y eficaz algunos trait, veamos un listado de ellos:

  • Clone, este crea un clon del objeto
  • Copy, este crea una copia del objeto, no es lo mismo que el anterior
  • Debug, nos provee un codigo de depuracion
  • Default, nos da un valor predeterminado para un tipo
  • Eq, es similar a PartialEq excepto para los parametros de un struct
  • Hash, para poder computar un hash desde &T
  • Ord, estos son todos los tipos que forman un order total para todos los tipos
  • PartialEq, este solo chequea un subconjunto de un struct
  • PartialOrd, valores que se compara para crear un orden de clasificacion
Anuncios

Para entenderlo vamos a ver un ejemplo simple para verlo en accion, para ello crearemos un nuevo ejemplo que llamaremos derivar, una vez creado vamos al archivo main.rs y modificaremos el codigo generado con el siguiente:

main.rs

#[derive(PartialEq, PartialOrd)]
struct Centimetros(f64);

#[derive(Debug)]
struct Pulgadas(i32);

impl Pulgadas
{
	fn a_cm(&self) -> Centimetros
	{
		let &Pulgadas(pulgadas) = self;
		Centimetros(pulgadas as f64 * 2.4)
	}
}

struct Segundos(i32);

fn main() 
{
	let _un_segundo = Segundos(1);

	let pie = Pulgadas(12);
	println!("Un pie equivale a {:?}", pie);

	let metro = Centimetros(100.0);
	let cmp =
		if pie.a_cm() < metro
		{
			"mas chico"
		} else {
			"mas grande"
		};
	println!("Un pie es {} que un metro.", cmp);
}
Anuncios
Anuncios

Nuestro primer derive nos permitira que el struct tuple llamado Centimetros pueda ser comparados con otros elementos, el segundo derive tendra otro struct al cual denominamos Pulgadas y tendra la posibilidad de ser impreso para depuracion, luego tendremos una implementacion para la struct Pulgadas, en ella tendremos un metodo llamado a a_cm, esta devolvera valores de tipo Centinetros porque como su nombre lo indica transformara valores de pulgadas a centimetros, observen que asignaremos el valor contenido en self a una variable llamada pulgadas, luego usamos el struct anterior y como argumento pasamos la variable anterior y lo «casteamos» como un f64 para finalmente multiplicarlo por 2.4 para convertirlo, esto sera el valor a devolver por nuestro metodo, lo siguiente es un struct que simplemente es por fuera de los derive.

Anuncios
Anuncios

En el main tenemos varias cosas interesantes, el primero es un objeto del ultimo struct pero vean que tiene el guion bajo para indicarle al compilador que lo tenemos creado pero no sera usado en ningun momento, si quieren saber mas sobre el guion bajo les recomiento este post, despues de esto nuestro primer paso sera crear un objeto del struct Pulgadas, lo siguiente sera una linea para mostrar el valor contenido en pie, luego crearemos un nuevo objeto pero para el struct Centimetros con un valor, nuestro siguiente paso sera una nueva variable que contendra un condicional donde usaremos el valor almacenado en pie y haremos un llamado al metodo a_cm para luego compararlo con nuestro objeto metro, en la primera condicion chequeamos si el valor devuelto por el metodo es menor a metro, en caso de ser verdadero asignara un mensaje de que es mas chico a cmp, de lo contrario asignara el mensaje que es mas grande, por ultimo mostraremos el valor almacenado en cmp, compilemos y veamos su salida:

tinchicus@dbn001vrt:~/lenguajes/rust/derivar$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/derivar`
Un pie equivale a Pulgadas(12)
Un pie es mas chico que un metro.
tinchicus@dbn001vrt:~/lenguajes/rust/derivar$
Anuncios

Como pueden ver el codigo funciono perfectamente pero para entenderlo un poco mejor vamos a agregar la siguiente linea despues de la creacion del objeto _un_segundo:

println!("Un segundo es: {:?}", _un_segundo);
Anuncios

Esto lo usaremos para mostrar a nuestro objeto tal como hicimos con pie, compilemos y veamos su salida:

tinchicus@dbn001vrt:~/lenguajes/rust/derivar$ cargo build
   Compiling derivar v0.1.0 (/home/tinchicus/lenguajes/rust/derivar)
error[E0277]: `Segundos` doesn't implement `Debug`
  --> src/main.rs:21:34
   |
21 |     println!("Un segundo es: {:?}", _un_segundo);
   |                                     ^^^^^^^^^^^ `Segundos` cannot be formatted using `{:?}`
   |
   = help: the trait `Debug` is not implemented for `Segundos`
   = note: add `#[derive(Debug)]` to `Segundos` or manually `impl Debug for Segundos`
   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `derivar` due to previous error
tinchicus@dbn001vrt:~/lenguajes/rust/derivar$
Anuncios

Observen que nos devolvio un error, esto es debido a lo que indica al comienzo, no se implemento el trait Debug tal como hicimos con Pulgadas, y si observan nos da dos opciones para solucionarlo, la primera es usar a derive y sino usar a impl, esta segunda opcion es mas compleja pero nos sera mas util si es necesario implementar operaciones mas complejas.

Anuncios

En resumen, hoy hemos visto el atributo derive, este es util para implementar de forma rapida trait para nuestros struct, vimos un breve listado de los disponibles, asi como tambien un breve ejemplo para verlo en accion y una pequeña modificacion para ver como realmente funciona, 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