La macro dbg!
e .inspect()
dbg!
dbg!
es una macro muy útil para volcar información. Es una buena alternativa a println!
porque es más fácil de teclear y da más información.
fn main() { let my_number = 8; dbg!(my_number); }
Esto imprime [src\main.rSs:4] my_number = 8
.
Además, dbg!
se puede poner en muchos otros lugares, incluso envolviendo código en ella. Por ejemplo, en el siguiente código:
fn main() { let mut my_number = 9; my_number += 10; let new_vec = vec![8, 9, 10]; let double_vec = new_vec.iter().map(|x| x * 2).collect::<Vec<i32>>(); }
Se crea una variable mutable y se modifica después. A continuación se crea un vec
y se utiliza iter
, map
y collect
para crear un nuevo vec
. Se puede añadir dbg!
en casi cualquier sitio del código anterior. Lo que hace esta macro es pedirle al compilador que "le diga qué está haciendo en este momento" y este se lo dice.
fn main() { let mut my_number = dbg!(9); dbg!(my_number += 10); let new_vec = dbg!(vec![8, 9, 10]); let double_vec = dbg!(new_vec.iter().map(|x| x * 2).collect::<Vec<i32>>()); dbg!(double_vec); }
El código anterior imprime primero:
[src\main.rs:3] 9 = 9
y después:
[src\main.rs:4] my_number += 10 = ()
y sigue con:
[src\main.rs:6] vec![8, 9, 10] = [
8,
9,
10,
]
y la siguiente muestra incluso el valor de la expresión:
[src\main.rs:8] new_vec.iter().map(|x| x * 2).collect::<Vec<i32>>() = [
16,
18,
20,
]
y:
[src\main.rs:10] double_vec = [
16,
18,
20,
]
.inspect()
.inspect()
es parecido a dbg!
, pero se usa como .map
en un iterador. Recibe un elemento iterador y se puede hacer lo que se quiera con él, el valor continuará en la cadena de funciones sin modificar. Por ejemplo, en el siguiente código:
fn main() { let new_vec = vec![8, 9, 10]; let double_vec = new_vec .iter() .map(|x| x * 2) .collect::<Vec<i32>>(); }
Se quiere tener información sobre lo que va haciendo el código. Así que se puede añadir .inspect()
en dos puntos:
fn main() { let new_vec = vec![8, 9, 10]; let double_vec = new_vec .iter() .inspect(|first_item| println!("El elemento contiene: {}", first_item)) .map(|x| x * 2) .inspect(|next_item| println!("Y después vale: {}", next_item)) .collect::<Vec<i32>>(); }
Que imprime:
El elemento contiene: 8
Y después vale: 16
El elemento contiene: 9
Y después vale: 18
El elemento contiene: 10
Y después vale: 20
Como .inspect()
recibe de parámetro un cierre (closure), se puede codificar todo lo que se necesite:
fn main() { let new_vec = vec![8, 9, 10]; let double_vec = new_vec .iter() .inspect(|first_item| { println!("El elemento es: {}", first_item); match **first_item % 2 { // eL primer elemento es un &i32 ** 0 => println!("Es par."), _ => println!("Es impar."), } println!("En binario es {:b}.", first_item); }) .map(|x| x * 2) .collect::<Vec<i32>>(); }
Que imprime:
El elemento es: 8
Es par.
En binario es 1000.
El elemento es: 9
Es impar.
En binario es 1001.
El elemento es: 10
Es par.
En binario es 1010.