Volver a la página principal
viernes 2 agosto 2024
21

Cómo funciona el ownership en Rust

Principios Básicos del Ownership en Rust

El sistema de ownership en Rust se basa en tres principios fundamentales:

1. Cada valor en Rust tiene un propietario.

2. Solo puede haber un propietario a la vez.

3. Cuando el propietario sale del alcance (scope), el valor se elimina.

Estos principios ayudan a garantizar que la memoria sea gestionada de manera eficiente y segura, evitando errores comunes como los punteros colgantes y las fugas de memoria.

Variables y Ownership

Cuando declaras una variable en Rust, se convierte en el propietario del valor asignado a ella. Por ejemplo:

fn main() {
    let x = 5;
    // x es el propietario del valor 5
}

En este caso, x es el propietario del valor 5. Cuando x sale del alcance al final del bloque main, el valor 5 se elimina automáticamente.

Transferencia de Propiedad: Move Semantics

Rust utiliza el concepto de "move semantics" para transferir la propiedad de un valor de una variable a otra. Cuando se mueve un valor, la variable original ya no es el propietario y no puede ser utilizada. Ejemplo:

fn main() {
    let s1 = String::from("hello");
    let s2 = s1;
    // s1 ya no es válido
    println!("{}", s2); // Funciona
    // println!("{}", s1); // Error: s1 no es válido
}

En este caso, la propiedad del String se mueve de s1 a s2, y s1 ya no es válido.

Préstamo de Valores: Borrowing

A veces, necesitas acceder a un valor sin tomar su propiedad. Rust permite el préstamo de valores mediante referencias. Hay dos tipos de referencias: referencias inmutables y referencias mutables.

Referencias Inmutables

Las referencias inmutables permiten leer un valor sin modificarlo:

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);
    println!("La longitud de '{}' es {}", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

En este ejemplo, &s1 crea una referencia inmutable a s1 que se pasa a la función calculate_length.

Referencias Mutables

Las referencias mutables permiten modificar un valor:

fn main() {
    let mut s = String::from("hello");
    change(&mut s);
    println!("{}", s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

Aquí, &mut s crea una referencia mutable que se pasa a la función change, permitiendo modificar el String.

Reglas de Borrowing

Rust impone reglas estrictas para el borrowing para garantizar la seguridad:

1. Puedes tener cualquier número de referencias inmutables, pero solo una referencia mutable a un valor en un momento dado.

2. Las referencias deben ser siempre válidas.

Estas reglas evitan condiciones de carrera y garantizan la seguridad en el acceso concurrente a datos.

Vida Útil (Lifetimes)

Las lifetimes en Rust aseguran que las referencias sean válidas mientras se necesiten. Aunque Rust generalmente puede inferir las lifetimes, a veces es necesario anotarlas explícitamente.

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

En este ejemplo, 'a es una lifetime que indica que la referencia devuelta será válida mientras ambas referencias x e y sean válidas.

Ownership en Colecciones

El ownership también se aplica a las colecciones en Rust, como vectores y mapas hash. Al añadir un valor a una colección, la colección se convierte en el propietario del valor.

fn main() {
    let v = vec![1, 2, 3];
    let v2 = v;
    // v ya no es válido
    println!("{:?}", v2);
}

Aquí, la propiedad del vector v se mueve a v2, y v ya no es válido.

Ownership y Concurrencia

El sistema de ownership de Rust también facilita la escritura de código concurrente seguro. Al usar el ownership y las referencias, Rust puede prevenir condiciones de carrera y otros problemas de concurrencia.

use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(move || {
        println!("{:?}", v);
    });

    handle.join().unwrap();
}

En este caso, move transfiere la propiedad del vector v al hilo, asegurando que no haya problemas de concurrencia.

Etiquetas:
rust
Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer