Created
December 13, 2025 08:03
-
-
Save gusdelact/9a7e4e0ebca88970377a33854b6700a4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ------------------------------------------------------------ | |
| // Ejemplo didáctico: referencias mutables, structs, arrays, | |
| // swap y un árbol binario con Box + Option (estilo C → Rust). | |
| // ------------------------------------------------------------ | |
| #[derive(Debug)] | |
| struct A { | |
| c1: u8, | |
| c2: u8, | |
| } | |
| /// f1: recibe una referencia mutable a un u8. | |
| /// - Lee el valor actual (desreferenciando) y lo copia en `x`. | |
| /// - Incrementa `x` (solo la copia local). | |
| /// - Incrementa el valor original a través de la referencia. | |
| /// - Regresa `x` (que es independiente del valor final en memoria). | |
| fn f1(p0: &mut u8) -> u8 { | |
| // Copiamos el valor apuntado por p0 (u8 es Copy, así que se copia barato) | |
| let mut x = *p0; | |
| // Incrementamos la copia local | |
| x = x + 1; | |
| // Modificamos el valor original (el que vive fuera de la función) | |
| *p0 = *p0 + 1; | |
| // Regresamos la copia local incrementada | |
| x | |
| } | |
| /// f2: recibe una referencia mutable a una estructura A. | |
| /// - Modifica sus campos in-place. | |
| /// - Imprime el contenido y la dirección donde vive la estructura. | |
| fn f2(p1: &mut A) { | |
| // Acceso directo a campos vía la referencia mutable | |
| p1.c1 = p1.c1 + 1; | |
| p1.c2 = p1.c2 + 1; | |
| // Debug: imprime el estado actual de la estructura | |
| println!("{:?}", p1); | |
| // Imprime la dirección (puntero) donde vive el objeto apuntado por p1 | |
| println!("{:p}", p1); | |
| } | |
| /// f3: demuestra el uso de una referencia mutable "re-asignable" | |
| /// (similar al uso de un puntero en C, pero con reglas seguras). | |
| fn f3() { | |
| let mut x: u8 = 1; | |
| let mut y: u8 = 2; | |
| // Arreglo fijo de 10 bytes, inicializado a 0 | |
| let mut z: [u8; 10] = [0; 10]; | |
| // Referencia mutable a u8 (nota: NO puede ser null) | |
| let mut ip: &mut u8; | |
| // ip apunta a x | |
| ip = &mut x; | |
| // y toma el valor apuntado por ip (o sea, el valor de x) | |
| y = *ip; | |
| // cambiamos x a través de ip | |
| *ip = 0; | |
| // ahora ip apunta al primer elemento del arreglo z | |
| ip = &mut z[0]; | |
| // incrementamos el primer elemento (0 + 10) | |
| *ip = *ip + 10; | |
| // y toma el valor de z[0] + 1 | |
| y = *ip + 1; | |
| // incrementamos z[0] con el operador compuesto | |
| *ip += 1; | |
| // Mostramos el arreglo completo | |
| println!("{:?}", z); | |
| // y se usa solo para evitar warnings en algunos compiladores/configs | |
| let _ = y; | |
| } | |
| /// swap: intercambio clásico, estilo C, usando referencias mutables. | |
| /// - Equivalente conceptual a swap(&mut a, &mut b). | |
| fn swap(px: &mut i8, py: &mut i8) { | |
| // temp guarda una copia del valor apuntado por px | |
| let temp: i8 = *px; | |
| // px toma el valor de py | |
| *px = *py; | |
| // py toma el valor original de px (guardado en temp) | |
| *py = temp; | |
| } | |
| /// f4: demuestra cómo modelar un árbol binario de forma idiomática en Rust: | |
| /// - `Box<TNode>`: el hijo vive en el heap. | |
| /// - `Option<Box<TNode>>`: reemplaza el clásico NULL. | |
| fn f4() { | |
| // Struct local a la función (solo visible dentro de f4) | |
| #[derive(Debug)] | |
| struct TNode { | |
| word: String, | |
| count: i32, | |
| left: Option<Box<TNode>>, | |
| right: Option<Box<TNode>>, | |
| } | |
| // Nodo hoja simple (sin hijos) | |
| let _node1 = TNode { | |
| word: "hello".to_string(), | |
| count: 1, | |
| left: None, | |
| right: None, | |
| }; | |
| // Nodo con hijo izquierdo | |
| let _node2 = TNode { | |
| word: "root".to_string(), | |
| count: 1, | |
| left: Some(Box::new(TNode { | |
| word: "left".to_string(), | |
| count: 1, | |
| left: None, | |
| right: None, | |
| })), | |
| right: None, | |
| }; | |
| // Creamos un nodo en el heap (Box) para poder "poseerlo" desde otro nodo | |
| let first = Box::new(TNode { | |
| word: "first".to_string(), | |
| count: 1, | |
| left: None, | |
| right: None, | |
| }); | |
| // second toma ownership de `first` en su campo right. | |
| // Importante: después de esto, ya NO puedes usar la variable `first`. | |
| let _second = TNode { | |
| word: "second".to_string(), | |
| count: 1, | |
| left: None, | |
| right: Some(first), | |
| }; | |
| // _second vive hasta el final de f4; al salir, se libera todo automáticamente. | |
| } | |
| fn main() { | |
| // ------------------------------------------------------------ | |
| // 1) Prueba con u8 y paso por referencia mutable (f1) | |
| // ------------------------------------------------------------ | |
| let mut a: u8 = 0x32; // 50 en decimal | |
| println!("{:?}", a); | |
| a = 0x64; // 100 en decimal | |
| println!("{:?}", a); | |
| // f1 modifica `a` vía &mut, y regresa un valor (que aquí ignoramos) | |
| let _ret = f1(&mut a); | |
| // a ya fue incrementado dentro de f1 | |
| println!("{:?}", a); | |
| a = 0x74; // 116 en decimal | |
| println!("{:?}", a); | |
| // ------------------------------------------------------------ | |
| // 2) Prueba con struct A y paso por referencia mutable (f2) | |
| // ------------------------------------------------------------ | |
| let mut b = A { c1: 2, c2: 3 }; | |
| // Estado antes | |
| println!("{:?}", b); | |
| println!("{:p}", &b); // dirección de b en main | |
| // f2 modifica b in-place | |
| f2(&mut b); | |
| // Estado después | |
| println!("{:?}", b); | |
| println!("{:p}", &b); // debe ser la misma dirección | |
| // ------------------------------------------------------------ | |
| // 3) Prueba con referencias mutables re-asignables (f3) | |
| // ------------------------------------------------------------ | |
| f3(); | |
| // ------------------------------------------------------------ | |
| // 4) swap clásico con referencias mutables | |
| // ------------------------------------------------------------ | |
| let mut c: i8 = 1; | |
| let mut d: i8 = 2; | |
| swap(&mut c, &mut d); | |
| println!("{:?}", c); // 2 | |
| println!("{:?}", d); // 1 | |
| // ------------------------------------------------------------ | |
| // 5) Árbol binario con Box + Option (f4) | |
| // ------------------------------------------------------------ | |
| f4(); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment