Variables y Mutabilidad
## Objetivos de Aprendizaje
- Declarar e inicializar variables
- Comprender la mutabilidad en Rust
- Trabajar con tipos de datos de Rust
- Dominar la inferencia de tipos
- Usar anotaciones de tipo
## Variables
### Declaracion
```rust
let x = 5; // Variable inmutable
let mut y = 10; // Variable mutable
```
### Reglas de Nomenclatura
- Comenzar con letra o guion bajo
- Puede contener letras, digitos, guiones bajos
- Sensible a mayusculas/minusculas
- No se pueden usar palabras reservadas
```rust
let age = 25; // Valido
let _count = 0; // Valido (suprime advertencia)
let total_price = 99.99; // Valido
// let 2ndPlace = 1; // Invalido: comienza con numero
// let let = 5; // Invalido: palabra reservada
```
## Mutabilidad
### Inmutable por Defecto
```rust
let x = 5;
x = 6; // Error: no se puede asignar dos veces a una variable inmutable
```
### Haciendo Variables Mutables
```rust
let mut x = 5;
x = 6; // OK: x es mutable
println!("{}", x); // Imprime: 6
```
### Por que la Inmutabilidad?
- Previene errores por modificacion accidental
- Permite optimizaciones del compilador
- Hace el codigo mas facil de razonar
## Tipos de Datos
### Tipos Escalar
#### Tipos Enteros
| Tipo | Tamano | Con signo |
|------|--------|-----------|
| i8 | 8-bit | Si |
| i16 | 16-bit | Si |
| i32 | 32-bit | Si |
| i64 | 64-bit | Si |
| i128 | 128-bit | Si |
| isize | tamano del puntero | Si |
| u8 | 8-bit | No |
| u16 | 16-bit | No |
| u32 | 32-bit | No |
| u64 | 64-bit | No |
| u128 | 128-bit | No |
| usize | tamano del puntero | No |
```rust
let a: i32 = 100; // Decimal
let b: i32 = 0x64; // Hexadecimal
let c: i32 = 0o144; // Octal
let d: i32 = 0b1100100; // Binario
let e: i32 = b'C'; // Literal de byte
let large: i64 = 9_000_000_000; // Guiones bajos para legibilidad
```
#### Tipos de Punto Flotante
```rust
let f1: f64 = 3.14; // 64-bit, defecto
let f2: f32 = 3.14; // 32-bit
println!("{}", std::f64::consts::PI); // Constante matematica
```
#### Tipo Booleano
```rust
let is_active = true;
let is_valid: bool = false;
```
#### Tipo Caracter
```rust
let c1 = 'a'; // Caracter ASCII
let c2 = 'Z';
let c3 = '\u{1F600}'; // Emoji Unicode
```
### Tipos Compuestos
#### Tupla
```rust
let tup: (i32, f64, u8) = (500, 6.4, 1);
// o
let tup = (500, 6.4, 1);
let (x, y, z) = tup; // Desestructuracion
println!("{} {} {}", x, y, z);
let first = tup.0; // Acceso por indice
let second = tup.1;
```
#### Arreglo
```rust
let arr: [i32; 5] = [1, 2, 3, 4, 5];
// o
let arr = [1, 2, 3, 4, 5];
let first = arr[0]; // Acceso por indice
let len = arr.len(); // Longitud del arreglo
// Arreglo con el mismo valor
let zeros = [0; 5]; // [0, 0, 0, 0, 0]
```
### Inferencia de Tipos
```rust
let x = 5; // El compilador infiere i32
let y = 3.14; // El compilador infiere f64
let name = "Alice"; // El compilador infiere &str
```
### Anotaciones de Tipo
```rust
let x: i32 = 5;
let y: f64 = 3.14;
let name: &str = "Alice";
let arr: [i32; 3] = [1, 2, 3];
```
## Constantes
### const vs let
```rust
let x = 5; // Variable inmutable (el compilador lo exige)
const MAX_SIZE: i32 = 100; // Constante en tiempo de compilacion
const PI: f64 = 3.14159265359; // Anotacion de tipo requerida
const MESSAGE: &str = "Hello"; // Slice de string
```
### Diferencias
| Caracteristica | let | const |
|---------|-----|-------|
| Mutabilidad | Con `mut` | Nunca |
| Anotacion de tipo | Opcional | Requerida |
| Evaluacion | Runtime | Tiempo de compilacion |
| Alcance | Bloque | Global |
## Conversion de Tipos
### Operador as
```rust
let x: i32 = 5;
let y: f64 = x as f64; // i32 a f64
let z: f64 = 3.99;
let w: i32 = z as i32; // Trunca a 3
let c: char = 65 as char; // Numero a caracter
let n: u8 = b'A'; // Literal de byte
```
### Parsear String a Numero
```rust
let s = "42";
let n: i32 = s.parse().unwrap(); // String a i32
let n: Result = s.parse();
let s = "3.14";
let f: f64 = s.parse().unwrap(); // String a f64
```
### Numero a String
```rust
let n = 42;
let s = n.to_string(); // i32 a String
let s = format!("{}", n); // Usando macro format
let f = 3.14;
let s = f.to_string();
```
## Alcance de Variables
```rust
fn main() {
let x = 10;
{
let y = 20; // Alcance interno
println!("{} {}", x, y); // OK: ambos visibles
}
println!("{}", x); // OK: x visible
// println!("{}", y); // Error: y no esta en alcance
}
```
## Shadowing
```rust
let x = 5;
let x = x + 1; // Enmasca la x anterior
let x = x * 2; // Enmasca de nuevo
println!("{}", x); // Imprime: 12
// Shadowing con diferente tipo
let spaces = " ";
let spaces = spaces.len(); // Ahora es i32
```
## Resumen
- Las variables son inmutables por defecto
- Usa `mut` para variables mutables
- Tipos escalares: enteros, flotantes, booleanos, caracteres
- Tipos compuestos: tuplas, arreglos
- La inferencia de tipos reduce la verbosidad
- Las constantes usan la palabra clave `const` (tiempo de compilacion)
- Usa `as` para conversion de tipos
- El shadowing permite redeclarar variables
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →