Métodos Mutables
Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 3 de 61.
A veces los métodos necesitan hacer algo más que solo leer datos: necesitan cambiarlos. Para crear métodos que puedan modificar los campos de una estructura, usamos &mut self en lugar de &self.
La palabra clave mut indica un préstamo mutable, otorgando al método permiso para alterar el estado interno de la instancia:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
Observa que increment y decrement usan &mut self porque modifican value, mientras que get usa &self ya que solo lee los datos.
Al llamar a métodos mutables, la instancia misma debe declararse como mutable:
fn main() {
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
}
Si olvidas la palabra clave mut al crear la instancia, Rust te impedirá llamar a cualquier método &mut self en ella. Esto asegura que siempre estés al tanto de cuándo tus datos podrían cambiar.
Desafío
FácilCrea una estructura BankAccount con un solo campo: balance (i32).
Añade un bloque de implementación para BankAccount con tres métodos:
deposit— toma&mut selfy unamount: i32, suma el monto al saldowithdraw— toma&mut selfy unamount: i32, resta el monto del saldoget_balance— toma&selfy devuelve el saldo actual comoi32
Recibirás tres entradas:
- Primera línea: el saldo inicial (i32)
- Segunda línea: el monto a depositar (i32)
- Tercera línea: el monto a retirar (i32)
Crea una instancia mutable de BankAccount con el saldo inicial, luego deposita el monto dado, retira el monto dado y muestra por pantalla el saldo final.
Formato de salida esperado:
{final_balance}Hoja de referencia
Los métodos que modifican los campos de una estructura utilizan &mut self (préstamo mutable), mientras que los métodos que solo leen datos utilizan &self:
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
fn decrement(&mut self) {
self.value -= 1;
}
fn get(&self) -> i32 {
self.value
}
}
Para llamar a métodos mutables, la instancia debe declararse como mutable con let mut:
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("{}", counter.get()); // 2
counter.decrement();
println!("{}", counter.get()); // 1
Sin la palabra clave mut en la instancia, Rust impedirá llamar a cualquier método &mut self.
Pruébalo tú mismo
use std::io;
// TODO: Define la estructura BankAccount aquí
// TODO: Agrega el bloque de implementación para BankAccount con los métodos deposit, withdraw y get_balance
fn main() {
let mut input = String::new();
// Leer el saldo inicial
io::stdin().read_line(&mut input).expect("Failed to read line");
let initial_balance: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// Leer el monto del depósito
io::stdin().read_line(&mut input).expect("Failed to read line");
let deposit_amount: i32 = input.trim().parse().expect("Invalid number");
input.clear();
// Leer el monto del retiro
io::stdin().read_line(&mut input).expect("Failed to read line");
let withdraw_amount: i32 = input.trim().parse().expect("Invalid number");
// TODO: Crear una instancia mutable de BankAccount con initial_balance
// TODO: Llamar a deposit con deposit_amount
// TODO: Llamar a withdraw con withdraw_amount
// TODO: Imprimir el saldo final usando get_balance
}Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1Métodos y Comportamiento
Intro a Bloques de ImplementaciónEl Parámetro SelfMétodos MutablesFunciones AsociadasMúltiples Bloques de ImplementaciónEncadenamiento de MétodosResumen - Acciones de Rectángulo4Proyecto: Mascota virtual
Definir la mascotaAlimentar a la mascota7Traits estándar
El trait DebugEl trait DisplayClone y CopyTraits de igualdadResumen - Punto imprimible10Proyecto: Sistema de documentos
El Trait DrawComponente de texto2Encapsulamiento y módulos
Conceptos básicos de módulosLa palabra clave PublicCampos privadosGettersSettersRepaso - Casillero seguro5Genéricos
Estructuras genéricasMétodos genéricosMúltiples tipos genéricosFunciones genéricasResumen - Punto de coordenadas8Traits como límites
Sintaxis de límites de traitsLímites múltiplesLa cláusula whereRetornar tipos con traitsResumen: Impresora genérica11Patrones de diseño en Rust
Patrón NewtypeComposiciónEl Trait DropFrom e IntoResumen - Mock de Smart Pointer3Enums avanzados
Enums con datosMétodos en EnumsCoincidencia de variantes de datosEl Enum Option revisitadoResumen - Enum Shape6Definición de Traits
¿Qué es un Trait?Implementación de TraitsImplementaciones por defectoSobrescribir valores por defectoTraits con parámetrosResumen - Reproductor multimedia