← Rust EspañolChapter 03 of 13

Propiedad

## Objetivos de Aprendizaje - Comprender las reglas de propiedad de Rust - Dominar el prestamo con referencias - Aprender los fundamentos de tiempos de vida - Evitar errores comunes de propiedad ## Que es la Propiedad? La propiedad es el sistema unico de Rust para gestionar la memoria. Cada valor tiene un solo propietario, y cuando el propietario sale del alcance, el valor se descarta. ## Reglas de Propiedad 1. Cada valor tiene exactamente un propietario 2. Solo puede haber un propietario a la vez 3. Cuando el propietario sale del alcance, el valor se descarta ```rust fn main() { let s1 = String::from("hello"); // s1 es el propietario del string let s2 = s1; // La propiedad se mueve a s2 // println!("{}", s1); // Error: s1 ya no es valido println!("{}", s2); // OK: s2 es el propietario del valor } ``` ## Semantica de Movimiento ### Strings vs Literales ```rust // String (alojado en heap) - SE MUEVE let s1 = String::from("hello"); let s2 = s1; // s1 se mueve a s2 // s1 ya no es valido // Literales de string (&str) - SE COPIAN (Trait Clone) let s1 = "hello"; let s2 = s1; // s1 se copia a s2 println!("{} {}", s1, s2); // Ambos son validos ``` ### Tipos Enteros - Siempre se Copian ```rust let x = 5; let y = x; // Copia (i32 implementa Copy) println!("{} {}", x, y); // Ambos son validos ``` ## Clone y Copy ### Clone (Copia Profunda) ```rust let s1 = String::from("hello"); let s2 = s1.clone(); // Copia profunda de datos del heap println!("{} {}", s1, s2); // Ambos son validos ``` ### Trait Copy (Datos de Pila) ```rust // Tipos que implementan Copy (solo pila): // - Todos los tipos enteros // - Todos los tipos de punto flotante // - Booleano // - Caracter // - Tupla de tipos Copy // - Arreglo de tipos Copy let x = (1, 2, 3); let y = x; // Copia, ambos validos ``` ## Propiedad y Funciones ### Pasar Valores a Funciones ```rust fn main() { let s = String::from("hello"); takes_ownership(s); // El valor de s se mueve a la funcion // println!("{}", s); // Error: s ya no es valido let x = 5; makes_copy(x); // x se copia (i32 es Copy) println!("{}", x); // OK: x sigue siendo valido } fn takes_ownership(s: String) { println!("{}", s); } // s se descarta aqui fn makes_copy(x: i32) { println!("{}", x); } // x se descarta aqui ``` ### Valores de Retorno y Alcance ```rust fn main() { let s1 = gives_ownership(); // La funcion devuelve la propiedad let s2 = String::from("hello"); let s3 = takes_and_returns(s2); // s2 se mueve adentro, s3 se devuelve } fn gives_ownership() -> String { let s = String::from("hello"); s // Devuelve y mueve al llamador } fn takes_and_returns(s: String) -> String { s // Devuelve y mueve al llamador } ``` ## Prestamo ### Referencias Una referencia te permite acceder a un valor sin tomar la propiedad. ```rust fn main() { let s1 = String::from("hello"); let len = calculate_length(&s1); // Pasa referencia a s1 println!("{} has length {}", s1, len); // s1 sigue siendo valido } fn calculate_length(s: &String) -> usize { s.len() } // s sale del alcance, pero NO se descarta ``` ### Referencias Mutables ```rust fn main() { let mut s = String::from("hello"); change(&mut s); println!("{}", s); } fn change(s: &mut String) { s.push_str(", world"); } ``` ### Reglas de Prestamo 1. Una referencia mutable O cualquier numero de referencias inmutables 2. Las referencias siempre deben ser validas (sin referencias colgantes) ```rust let mut s = String::from("hello"); let r1 = &s; // OK let r2 = &s; // OK: multiples referencias inmutables // let r3 = &mut s; // Error: no se puede prestar mutablemente mientras existen referencias inmutables println!("{} {}", r1, r2); // r1 y r2 ya no se usan despues de este punto let r3 = &mut s; // OK: las referencias inmutables terminaron r3.push_str(" world"); ``` ## Tiempos de Vida ### Que son los Tiempos de Vida? Los tiempos de vida son anotaciones que ayudan al compilador a asegurar que las referencias sean validas. ```rust fn main() { let r; { let x = 5; r = &x; // Error: x no vive lo suficiente } println!("{}", r); } ``` ### Anotaciones de Tiempo de Vida ```rust // &'a significa que la referencia vive al menos tanto como el tiempo de vida 'a fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn main() { let s1 = String::from("long string"); let result; { let s2 = String::from("xyz"); result = longest(s1.as_str(), s2.as_str()); println!("Longest: {}", result); } // result seria invalido aqui si se usara } ``` ### Eliminacion de Tiempos de Vida El compilador usa reglas para inferir tiempos de vida en casos comunes: ```rust // Estos son equivalentes: fn first_word(s: &str) -> &str { } fn first_word<'a>(s: &'a str) -> &'a str { } // Regla 1: Cada parametro de referencia obtiene su propio tiempo de vida // Regla 2: Si hay exactamente un tiempo de vida de entrada, se aplica a la salida // Regla 3: Si hay un &self o &mut self, se aplica a la salida ``` ### Tiempo de Vida Estatico `'static` significa que la referencia vive durante todo el programa: ```rust let s: &'static str = "I live forever"; ``` Los literales de string tienen tiempo de vida `'static`. ## El Tipo Slice Los slices son referencias a una porcion de una coleccion: ```rust let s = String::from("hello world"); let hello = &s[0..5]; // Igual que &s[..5] let world = &s[6..11]; // Igual que &s[6..] // Slice de string fn first_word(s: &str) -> &str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[0..i]; } } &s[..] } ``` ## Resumen - Cada valor tiene exactamente un propietario - Cuando la propiedad se mueve, la variable original se invalida - Los tipos Copy (primitivos) se copian en lugar de moverse - Clone crea una copia profunda - Las referencias piden prestadas valores sin tomar la propiedad - La referencia mutable permite modificar el valor prestado - Solo una referencia mutable O multiples referencias inmutables - Los tiempos de vida aseguran que las referencias sean validas mientras sea necesario - Los slices son referencias a porciones de datos

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →