Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Manejo de memoria en Rust: Ownership

Manejo de memoria en Rust: Ownership

Mozilla Perú - 28 Nov 2019

Lupo Montero

November 28, 2019
Tweet

More Decks by Lupo Montero

Other Decks in Programming

Transcript

  1. ToC Parte 1: Contexto • ¿Por qué importa el manejo

    de memoria? • ¿Qué es manejo de memoria? • Estrategias de manejo de memoria Parte 3: Un ejemplo • Threads • Race conditions • Mutex • Message passing • Shared state Parte 2: Ownership en Rust • Reglas de ownership • Valores, variables y tipos • String • Referencias y borrowing • Scope • Ownership y funciones • Slices
  2. Memory management Memory management is a form of resource management

    applied to computer memory. The essential requirement of memory management is to provide ways to dynamically allocate portions of memory to programs at their request, and free it for reuse when no longer needed. This is critical to any advanced computer system where more than a single process might be underway at any time. https://en.wikipedia.org/wiki/Memory_management
  3. Valores, variables y tipo de datos Primitivos (sized) Scalar let

    a: i32; let b = "hello"; Compound let a = (true, 1, “OMG”); let b = [1, 2, 3]; Complejos let s = String::from("hello"); let mut v = Vec::new(); let mut guess = String::new(); io::stdin().read_line(&mut guess) .expect("Failed to read line");
  4. Ciclo de vida de memoria Sin importar el lenguaje de

    programación, el ciclo de memoria es casi siempre parecido al siguiente: • Reservar la memoria necesaria (ej: malloc()) • Utilizarla (lectura, escritura) • Liberar la memoria una vez ya no es necesaria. (ej: free())
  5. Reglas de ownership • Cada valor (value) en Rust tiene

    una variable llamada su dueño (owner) • Solo puede haber un dueño (owner) a la vez. • Cuando el dueño (owner) sale fuera de ámbito (scope), el valor será descartado (dropped).
  6. Cada valor tiene una variable llamada su dueño let a

    = "hello"; let b = a; println!("{}", a); println!("{}", b); let a = String::from("hello"); let b = a; println!("{}", a); println!("{}", b);
  7. Copy vs Move vs Clone Copy (Stack-only) let x =

    5; let y = x; Move let s1 = String::from("hello"); let s2 = s1; Clone let s1 = String::from("hello"); let s2 = s1.clone();
  8. Solo puede haber un dueño (owner) a la vez. Para

    un tipo T: • T (owned) • &mut T (exclusive) • &T (shared) fn foo(s: String) { // s es ahora dueño del string println!("{:?}", s); // acá termina el scope de s y la memoria // asignada para esta variable se libera } let a = String::from(“hello”); let b = a; // b ahora es dueño / ownership se ha movido foo(b); // ownership se ha movido a foo
  9. … y el dueño puede prestarlo (referencias y borrowing) Para

    un tipo T: • T (owned) • &mut T (exclusive) • &T (shared) fn foo(s: &String) { // s toma prestado el valor println!("{:?}", s); } let a = String::from(“hello”); let b = &a; // b toma prestado una referencia de solo lectura foo(b); // pasamos la referencia foo(&a); // o una nueva referencia // acá termina el scope de a y la memoria // asignada para esta variable se libera
  10. Ámbito / Scope { // s is not valid here,

    it’s not yet declared let s = "hello"; // s is valid from this point forward // do stuff with s } // this scope is now over, and s is no longer valid
  11. Ownership y funciones fn main() { let s = String::from("hello");

    takes_ownership(s); let x = 5; makes_copy(x); let s1 = gives_ownership(); let s2 = String::from("hello"); let s3 = takes_and_gives_back(s2); } fn takes_ownership(some_string: String) { println!("{}", some_string); } fn makes_copy(some_integer: i32) { println!("{}", some_integer); } fn gives_ownership() -> String { let some_string = String::from("hello"); some_string } fn takes_and_gives_back(a_string: String) -> String { a_string }
  12. Slices let s = String::from("hello world"); let hello = &s[0..5];

    let world = &s[6..11]; // strings literales son slices!! let s = "Hello, world!"; 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[..] } let my_string = String::from("hello world"); let word = first_word(&my_string[..]); let my_string_literal = "hello world"; let word = first_word(&my_string_literal[..]); let word = first_word(my_string_literal);
  13. Fin