Getters
Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 11 de 61.
Con campos privados, el código externo no puede acceder directamente a los datos de tu struct. Pero a veces necesitas permitir que otros lean los datos sin darles la capacidad de cambiarlos. Aquí es donde entran los métodos getter.
Un getter es simplemente un método público que devuelve una referencia a un campo privado:
// wallet.rs
pub struct Wallet {
balance: f64,
}
impl Wallet {
pub fn new(initial: f64) -> Wallet {
Wallet { balance: initial }
}
pub fn balance(&self) -> f64 {
self.balance
}
}
El método balance() toma &self (acceso de solo lectura) y devuelve el valor del campo privado. En Rust, los getters suelen llevar el nombre del propio campo—no se necesita el prefijo get_.
Ahora el código externo puede leer el saldo a través del método:
// main.rs
mod wallet;
use wallet::Wallet;
fn main() {
let w = Wallet::new(100.0);
println!("Balance: {}", w.balance()); // ¡Funciona!
}
Para los campos que contienen datos propios como String, a menudo devolverás una referencia para evitar copias innecesarias:
pub fn name(&self) -> &String {
&self.name
}
Los getters te brindan un acceso de lectura controlado mientras mantienen el campo en sí protegido. La struct sigue a cargo de sus datos: el código externo puede mirar, pero no puede tocar.
Desafío
FácilVamos a construir un sistema de perfil de usuario que demuestre cómo los métodos getter proporcionan acceso de lectura controlado a datos privados.
Crearás dos archivos para organizar tu código:
profile.rs: Define una estructuraUserProfilecon dos campos privados:username(String) yage(u32). La estructura en sí debe ser pública, pero los campos deben permanecer privados. Implementa un constructor públiconewque reciba un nombre de usuario y una edad. Luego, añade dos métodos getter:username— devuelve una referencia al nombre de usuario (&String)age— devuelve el valor de la edad (u32)
main.rs: Importa tu módulo profile, crea unUserProfiley utiliza los métodos getter para imprimir la información del usuario.
Recuerda que los getters en Rust suelen llevar el mismo nombre que el campo; no es necesario el prefijo get_. Para los campos de tipo String, devuelve una referencia para evitar copias innecesarias.
Tu salida debe seguir este formato exacto:
Username: {username}
Age: {age}Por ejemplo, si creas un perfil con el nombre de usuario "alice" y la edad 25, la salida sería:
Username: alice
Age: 25Recibirás dos entradas: el nombre de usuario y la edad.
Hoja de referencia
Un método getter es un método público que proporciona acceso de solo lectura a un campo privado.
Los getters permiten que el código externo vea los datos sin poder modificarlos directamente:
pub struct Wallet {
balance: f64,
}
impl Wallet {
pub fn new(initial: f64) -> Wallet {
Wallet { balance: initial }
}
pub fn balance(&self) -> f64 {
self.balance
}
}
En Rust, los getters se nombran igual que el campo en sí; no es necesario el prefijo get_.
Para los campos que contienen datos en propiedad como String, devuelva una referencia para evitar copias innecesarias:
pub fn name(&self) -> &String {
&self.name
}
Uso de un método getter:
let w = Wallet::new(100.0);
println!("Balance: {}", w.balance());
Pruébalo tú mismo
mod profile;
use profile::UserProfile;
fn main() {
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let username = input1.trim().to_string();
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let age: u32 = input2.trim().parse().expect("Failed to parse age");
// TODO: Crear un UserProfile usando el constructor
// TODO: Usar los métodos getter para imprimir el nombre de usuario y la edad
// Formato:
// Username: {username}
// Age: {age}
}
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