Anuncios

Bienvenidos sean a este post, hoy veremos que pasa entre los canales y la propiedad.

Anuncios

En el post anterior hablamos sobre los canales y como nos ayuda a enviar informacion entre distintos threads, en este post hablamos sobre que es la propiedad (ownership) en una variable pero estos dos trabajan juntos para evitar inconvenientes a la hora de trabajar con nuestros codigos, tomemos el proyecto que creamos en el post anterior y modifiquemos el codigo de main.rs de la siguiente manera:

Anuncios
Nota:
Si no lo poseen generen un nuevo proyecto llamado canal.
Anuncios

main.rs

use std::thread;
use std::sync::mpsc;

fn main() 
{
	let (tx, rx) = mpsc::channel();

	thread::spawn(move || {
		let v = String::from("Hola");
		tx.send(v).unwrap();
		println!("V: {}", v);
	});

	let recibido = rx.recv().unwrap();
	println!("Recibido: {}", recibido);
}
Anuncios

Sin entrar en muchos detalles, este codigo genera un nuevo thread el cual transmite un String de este nuevo thread al principal y el otro lo recibe, para mas detalle les recomiendo el post anterior, en este caso lo unico diferente fue agregar un println para mostrar el valor de la variable v, compilemos y veamos que sucede:

tinchicus@dbn001vrt:~/lenguajes/rust/canal$ cargo build
   Compiling canal v0.1.0 (/home/tinchicus/lenguajes/rust/canal)
error[E0382]: borrow of moved value: `v`
  --> src/main.rs:11:21
   |
9  |         let v = String::from("Hola");
   |             - move occurs because `v` has type `String`, which does not implement the `Copy` trait
10 |         tx.send(v).unwrap();
   |                 - value moved here
11 |         println!("V: {}", v);
   |                           ^ value borrowed here after move

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

Como pueden ver no se pudo compilar porque al momento de querer mostrar el valor de la variable ya la enviamos al otro thread y no sabemos si en el destino no fue modificada, recuerden que los tipos primitivos manejan el Copy trait y estos tipos no, y principalmente este se ve afectada porque el metodo send es el encargado de tomar propiedad (ownership) sobre la informacion que estamos enviando, y esto evitara cualquier tipo de inconsistencia como comentamos anteriormente, recuerden que este lenguaje es memory-safe tal como mencionamos en este post, con todo esto comentado como podriamos solucionarlo? De una manera sencilla, para ello tomaremos este bloque:

	thread::spawn(move || {
		let v = String::from("Hola");
		tx.send(v).unwrap();
		println!("V: {}", v);
	});
Anuncios

Y lo cambiaremos de la siguiente manera:

	thread::spawn(move || {
		let v = String::from("Hola");
		println!("V: {}", v);
		tx.send(v).unwrap();
	});
Anuncios

Lo que hacemos es simplemente mostrar el mensaje antes de que le cambiemos la propiedad para que el compilador sepa perfectamente como se maneja la informacion, compilemos y veamos su salida:

tinchicus@dbn001vrt:~/lenguajes/rust/canal$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `target/debug/canal`
V: Hola
Recibido: Hola
tinchicus@dbn001vrt:~/lenguajes/rust/canal$
Anuncios

En resumen, hoy hemos visto un problema potencial que podemos tener entre los canales y la propiedad (ownership), como uno puede afectar al otro sin que nos demos cuenta, y tambien hemos visto como solucionarlo, espero les haya sido util 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

Donación

Es para mantenimento del sitio, gracias!

$1.50

Anuncio publicitario