Skip to content

Commit

Permalink
Merge pull request #10 from RustLangES/content-basic
Browse files Browse the repository at this point in the history
[CONTENT] Agregando el contenido "Basico del Lenguaje"
  • Loading branch information
SergioRibera authored Jun 20, 2024
2 parents d7823f6 + 09b7417 commit ee324e3
Show file tree
Hide file tree
Showing 32 changed files with 3,974 additions and 0 deletions.
Binary file modified bun.lockb
Binary file not shown.
File renamed without changes.
14 changes: 14 additions & 0 deletions content/2.basic/1.syntax.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
title: 'Sintaxis Básica'
description: ''
data:
type: 'transparent'
topicLevel: 'start'
position:
x: -700
y: 200
width: 320
align: 'center'
sourcePosition:
none: 'top'
targetPosition:
basic: 'right'
105 changes: 105 additions & 0 deletions content/2.basic/10.transfer-ownership.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: 'Transferencia de Ownership'
description: 'Transferencias de Ownership en Rust: Un Cambio Fundamental en la Gestión de Recursos'
draft: true
data:
type: 'custom'
topicLevel: 'start'
position:
x: -700
y: 600
width: 320
externalLinks:
- name: 'Libro Oficial'
english: false
link: 'https://book.rustlang-es.org/ch04-01-what-is-ownership?highlight=transferencia#valores-de-retorno-y-alcance'
---
## Transferencias de Ownership en Rust: Un Cambio Fundamental en la Gestión de Recursos

### Introducción

Rust es un lenguaje de programación que ha capturado la atención de desarrolladores por su enfoque único en la seguridad y el rendimiento. Un aspecto crucial que diferencia a Rust de otros lenguajes es su sistema de **ownership (propiedad)**. La **transferencia de ownership** es una característica clave de este sistema, que permite manejar la memoria de manera segura y eficiente. En este post, exploraremos en detalle cómo funcionan las transferencias de ownership en Rust y por qué son fundamentales para el paradigma de gestión de recursos del lenguaje.

### Concepto de Ownership en Rust

En Rust, cada valor en el programa tiene un único propietario. Esta variable propietaria es responsable de liberar los recursos asociados cuando sale del alcance (scope). Este enfoque asegura que no haya duplicaciones de liberación de memoria ni fugas de memoria, proporcionando una seguridad robusta en tiempo de compilación.

### ¿Qué es la Transferencia de Ownership?

La transferencia de ownership ocurre cuando un valor se mueve de una variable a otra, transfiriendo con ello la responsabilidad de gestionar ese valor. En Rust, esto se conoce como "mover" (move). Una vez que un valor ha sido movido, la variable original ya no puede usarse para acceder al valor, evitando así accesos inválidos a memoria.

### Ejemplo de Transferencia de Ownership

Consideremos el siguiente ejemplo para ilustrar cómo funciona la transferencia de ownership:

```rust
fn main() {
let s1 = String::from("Hello");
let s2 = s1; // s1 se mueve a s2
println!("{}", s2); // Esto funciona
// println!("{}", s1); // Esto causaría un error de compilación
}
```

En este código, la cadena `"Hello"` se asigna a `s1`. Luego, `s1` se mueve a `s2`, transfiriendo la propiedad. Intentar usar `s1` después de la transferencia causará un error de compilación porque `s1` ya no es válido.

### Transferencias de Ownership en Funciones

Las transferencias de ownership también ocurren cuando se pasan parámetros a funciones y cuando se retornan valores desde funciones. Veamos un ejemplo:

```rust
fn main() {
let s1 = String::from("Hello");
takes_ownership(s1); // s1 se mueve a la función
// println!("{}", s1); // Esto causaría un error de compilación
}

fn takes_ownership(some_string: String) {
println!("{}", some_string);
}
```

En este caso, `s1` se mueve a la función `takes_ownership`, transfiriendo la propiedad. Una vez que `s1` ha sido movido, ya no puede usarse en `main`.

### Retorno de Valores y Ownership

Rust también permite transferir ownership cuando se retorna un valor desde una función:

```rust
fn main() {
let s1 = gives_ownership();
println!("{}", s1);
}

fn gives_ownership() -> String {
let some_string = String::from("Hello");
some_string // se mueve al llamador
}
```

Aquí, la función `gives_ownership` crea una cadena y luego la retorna, transfiriendo la propiedad al llamador.

### Clonación: Copias en Lugar de Movimientos

En algunos casos, es posible que desees hacer una copia en lugar de mover un valor. Rust permite esto mediante el método `clone`, que crea una copia profunda del valor:

```rust
fn main() {
let s1 = String::from("Hello");
let s2 = s1.clone(); // Se clona s1
println!("{}", s1); // Esto funciona
println!("{}", s2); // Esto también funciona
}
```

### Beneficios de la Transferencia de Ownership

1. **Seguridad en Tiempo de Compilación:** Al transferir ownership de manera explícita, Rust asegura que no haya accesos inválidos a memoria ni liberaciones duplicadas.

2. **Control de Recursos:** La transferencia de ownership proporciona un control preciso sobre la vida útil de los recursos, lo que es crucial para el rendimiento y la eficiencia.

3. **Prevención de Errores Comunes:** Errores como las fugas de memoria y las condiciones de carrera se evitan gracias a las reglas de ownership y borrowing.

### Conclusión

La transferencia de ownership es un concepto central en Rust que redefine cómo gestionamos la memoria y los recursos. Al asegurar que cada valor tenga un único propietario y al validar las transferencias de ownership en tiempo de compilación, Rust proporciona un nivel de seguridad y eficiencia que es difícil de alcanzar en otros lenguajes. Aunque puede requerir un cambio de mentalidad para los desarrolladores acostumbrados a otros paradigmas, los beneficios que ofrece en términos de seguridad y control hacen que valga la pena adoptar este enfoque.
184 changes: 184 additions & 0 deletions content/2.basic/11.reference-and-mutability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
title: 'Referencias y Mutabilidad'
description: 'Referencias y Mutabilidad en Rust: Un Enfoque Seguro para la Gestión de Datos'
draft: true
data:
type: 'custom'
topicLevel: 'start'
position:
x: -700
y: 640
width: 320
externalLinks:
- name: 'Libro Oficial'
english: false
link: 'https://book.rustlang-es.org/ch04-02-references-and-borrowing'
---
## Referencias y Mutabilidad en Rust: Un Enfoque Seguro para la Gestión de Datos

### Introducción

Rust es un lenguaje de programación que se destaca por su enfoque en la seguridad y la eficiencia. Dos conceptos fundamentales que contribuyen a estos objetivos son las **referencias** y la **mutabilidad**. En este post, exploraremos cómo Rust maneja las referencias y la mutabilidad, y cómo estos conceptos trabajan juntos para proporcionar un sistema de gestión de memoria seguro y eficiente.

### Referencias: Acceso Seguro a los Datos

En Rust, una **referencia** es un tipo que permite acceder a los datos sin tomar la propiedad de ellos. Las referencias se crean utilizando el operador `&`, y pueden ser inmutables o mutables.

#### Referencias Inmutables

Una referencia inmutable permite leer los datos pero no modificarlos. Se crean utilizando `&`:

```rust
fn main() {
let s = String::from("Hello");
let len = calculate_length(&s); // Se pasa una referencia inmutable
println!("La longitud de '{}' es {}.", s, len);
}

fn calculate_length(s: &String) -> usize {
s.len() // Solo lectura
}
```

**Gráfico 1: Referencia Inmutable**

```plaintext
+-------+ +----------------------+
| s |-----> | "Hello" |
+-------+ +----------------------+
|
v
+-------+ +----------------------+
| len | | calculate_length(&s) |
+-------+ +----------------------+
```

#### Referencias Mutables

Una referencia mutable permite tanto leer como modificar los datos. Se crean utilizando `&mut`:

```rust
fn main() {
let mut s = String::from("Hello");
change(&mut s); // Se pasa una referencia mutable
println!("{}", s);
}

fn change(s: &mut String) {
s.push_str(", world"); // Modifica la cadena
}
```

**Gráfico 2: Referencia Mutable**

```plaintext
+-----------+ +----------------------+
| s |-----> | "Hello" |
+-----------+ +----------------------+
|
v
+-----------+ +----------------------+
| change | | change(&mut s) |
+-----------+ | "Hello, world" |
```

### Reglas de las Referencias

Rust aplica estrictas reglas para el uso de referencias, garantizando la seguridad y evitando condiciones de carrera:

1. **Solo una referencia mutable a la vez:** No puede haber más de una referencia mutable a un dato en un momento dado.
2. **No se permiten referencias mutables mientras existan referencias inmutables:** Un dato no puede tener una referencia mutable si existe alguna referencia inmutable activa.

#### Ejemplo de Violación de Reglas

Intentar violar estas reglas resultará en un error de compilación. Por ejemplo:

```rust
fn main() {
let mut s = String::from("Hello");
let r1 = &s; // Referencia inmutable
let r2 = &s; // Otra referencia inmutable
let r3 = &mut s; // Error: no se puede tener una referencia mutable mientras existan referencias inmutables
}
```

**Gráfico 3: Violación de Reglas de Referencia**

```plaintext
+-----------+ +----------------------+
| s |-----> | "Hello" |
+-----------+ +----------------------+
| |
| +-> r1 (inmutable)
|
+-> r2 (inmutable)
|
+-> r3 (mutable) - Error!
```

### Beneficios de las Reglas de Referencias

1. **Seguridad en Tiempo de Compilación:** Las reglas de referencias de Rust aseguran que no haya accesos concurrentes inseguros a los datos, eliminando condiciones de carrera.
2. **Control de la Mutabilidad:** Al restringir la mutabilidad a una única referencia a la vez, Rust evita modificaciones no controladas y mantiene la integridad de los datos.
3. **Prevención de Errores Comunes:** Muchos errores comunes en la programación, como los punteros colgantes y los accesos a memoria no válida, se previenen mediante estas reglas.

### Ejemplos Prácticos de Uso de Referencias y Mutabilidad

#### Ejemplo 1: Contador de Referencias

Un contador de referencias puede beneficiarse de las reglas de referencias de Rust para mantener un conteo seguro:

```rust
fn main() {
let count = 5;
let r1 = &count;
let r2 = &count;

println!("r1: {}, r2: {}", r1, r2);
}
```

**Gráfico 4: Contador de Referencias**

```plaintext
+---------+ +-------------+
| count |-----> | 5 |
+---------+ +-------------+
| |
| +-> r1 (inmutable)
|
+-> r2 (inmutable)
```

#### Ejemplo 2: Modificación Controlada

Controlar la modificación de un valor en una función sin transferir la propiedad:

```rust
fn main() {
let mut x = 10;
add_five(&mut x);
println!("x: {}", x);
}

fn add_five(n: &mut i32) {
*n += 5;
}
```

**Gráfico 5: Modificación Controlada**

```plaintext
+---------+ +-------------+
| x |-----> | 10 |
+---------+ +-------------+
|
v
+---------+ +-------------+
| add_five| | 10 + 5 |
+---------+ | 15 |
```

### Conclusión

Las referencias y la mutabilidad son conceptos esenciales en Rust que proporcionan un enfoque seguro y eficiente para la gestión de datos. Al aplicar estrictas reglas en tiempo de compilación, Rust garantiza la seguridad de la memoria y previene errores comunes en la programación. Estos mecanismos permiten a los desarrolladores escribir código robusto y libre de condiciones de carrera, mejorando la calidad y fiabilidad de las aplicaciones. Adoptar y comprender estos conceptos es crucial para aprovechar al máximo las capacidades de Rust y crear software seguro y eficiente.
Loading

0 comments on commit ee324e3

Please sign in to comment.