Structs
## Objetivos de Aprendizaje
- Definir e instanciar structs
- Usar sintaxis de metodos con impl
- Crear funciones asociadas
- Comprender structs de tupla
- Dominar la actualizacion de structs
## Definiendo Structs
### Struct Clasico
```rust
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect = Rectangle {
width: 30,
height: 50,
};
println!("{} x {}", rect.width, rect.height);
}
```
### Struct de Tupla
```rust
struct Point(i32, i32);
struct Color(u8, u8, u8);
fn main() {
let point = Point(10, 20);
let color = Color(255, 0, 0);
println!("{} {}", point.0, point.1);
println!("R {} G {} B {}", color.0, color.1, color.2);
}
```
### Struct Tipo Unidad
```rust
struct AlwaysEqual;
fn main() {
let _subject = AlwaysEqual;
}
```
## Instanciando Structs
### Crear Instancia
```rust
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
email: String::from("alice@example.com"),
username: String::from("alice123"),
active: true,
sign_in_count: 1,
};
}
```
### Abreviatura de Inicializacion de Campos
```rust
fn build_user(email: String, username: String) -> User {
User {
email, // Igual que email: email
username, // Igual que username: username
active: true,
sign_in_count: 1,
}
}
```
## Mutando Campos de Struct
```rust
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let mut rect = Rectangle {
width: 30,
height: 50,
};
rect.width = 40;
println!("{} x {}", rect.width, rect.height);
}
```
## Sintaxis de Metodos
### Bloque impl
```rust
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("Area: {}", rect.area());
}
```
### Metodos con Parametros
```rust
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
fn set_width(&mut self, width: u32) {
self.width = width;
}
}
```
### Funciones Asociadas
Funciones que no toman `self` como parametro:
```rust
impl Rectangle {
fn new(width: u32, height: u32) -> Rectangle {
Rectangle { width, height }
}
fn square(size: u32) -> Rectangle {
Rectangle { width: size, height: size }
}
}
fn main() {
let rect = Rectangle::new(30, 50);
let sq = Rectangle::square(20);
}
```
### Multiples Bloques impl
```rust
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
impl Rectangle {
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
```
## Sintaxis de Actualizacion de Struct
### Copiar Todos los Campos
```rust
struct Point {
x: i32,
y: i32,
z: i32,
}
fn main() {
let p1 = Point { x: 1, y: 2, z: 3 };
let p2 = Point {
x: 10,
..p1 // Copiar campos restantes de p1
};
println!("{} {} {}", p2.x, p2.y, p2.z); // 10 2 3
}
```
### Con Structs de Tupla
```rust
struct Point(i32, i32, i32);
fn main() {
let p1 = Point(1, 2, 3);
let p2 = Point(10, ..p1);
println!("{} {} {}", p2.0, p2.1, p2.2); // 10 2 3
}
```
## Propiedad en Structs
### Valores Propios
```rust
struct User {
username: String,
email: String,
}
fn main() {
let user = User {
email: String::from("alice@example.com"),
username: String::from("alice123"),
};
// user.email y user.username son propietarios de sus datos
}
```
### Valores de Referencia
```rust
struct User {
username: &str, // Se necesitan tiempos de vida!
email: &str,
}
// Mejor enfoque: usar String propio
struct User {
username: String,
email: String,
}
```
## Ejemplo: Rectangle con Metodos
```rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn new(width: u32, height: u32) -> Rectangle {
Rectangle { width, height }
}
fn square(size: u32) -> Rectangle {
Rectangle { width: size, height: size }
}
fn area(&self) -> u32 {
self.width * self.height
}
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
fn width(&self) -> u32 {
self.width
}
fn height(&self) -> u32 {
self.height
}
}
fn main() {
let rect = Rectangle::new(30, 50);
let sq = Rectangle::square(20);
println!("{:?}", rect);
println!("Area: {}", rect.area());
println!("Can hold square? {}", rect.can_hold(&sq));
}
```
## Trait Debug
```rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("{:?}", rect); // Formato Debug
println!("{:#?}", rect); // Debug bonito
}
```
## Resumen
- Los structs agrupan datos relacionados
- Los structs de tupla nombran colecciones de tuplas
- Los structs tipo unidad para tipos marcador
- Los metodos se definen en bloques `impl`
- `&self` pide prestada la instancia
- Las funciones asociadas no toman `self` (constructores)
- La sintaxis de actualizacion de struct `..` copia campos restantes
- Usa `#[derive(Debug)]` para salida de debug
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →