Menu
Coddy logo textTech

Setters

Parte da seção Programação Orientada a Objetos do Journey de Rust da Coddy. Lição 12 de 61.

Getters permitem que o código externo leia dados privados. Mas e se você precisar permitir que ele os altere? É aí que entram os métodos setter: métodos públicos que modificam campos privados de forma controlada.

Um setter básico recebe &mut self e um novo valor:

// wallet.rs
pub struct Wallet {
    balance: f64,
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Self { balance: initial }
    }
    
    pub fn balance(&self) -> f64 {
        self.balance
    }
    
    pub fn set_balance(&mut self, amount: f64) {
        self.balance = amount;
    }
}

Ao contrário dos getters, os setters em Rust geralmente usam o prefixo set_ para indicar claramente que modificam dados. O parâmetro &mut self é essencial. Ele concede ao método permissão para alterar os campos da struct.

O verdadeiro poder dos setters é a validação. Em vez de aceitar cegamente qualquer valor, você pode impor regras:

pub fn set_balance(&mut self, amount: f64) {
    if amount >= 0.0 {
        self.balance = amount;
    }
    // Valores negativos são silenciosamente ignorados
}

Agora a carteira se protege: não importa qual valor o código externo tente definir, o saldo nunca pode ficar negativo. Isso é encapsulamento em ação: a estrutura controla seus próprios invariantes, e o código externo simplesmente não pode colocá-la em um estado inválido.

challenge icon

Desafio

Fácil

Vamos criar um sistema de termostato que demonstra como setters podem impor regras para manter os dados válidos. Seu termostato terá uma configuração de temperatura que só poderá ser ajustada dentro de uma faixa segura.

Você criará dois arquivos para organizar seu código:

  • thermostat.rs: Defina uma struct Thermostat com um campo temperature privado (i32). A struct deve ser pública, mas o campo deve permanecer privado para protegê-lo de valores inválidos. Implemente:
    • Um construtor new que recebe uma temperatura inicial
    • Um getter temperature que retorna a temperatura atual
    • Um setter set_temperature que aceita apenas valores entre 10 e 30 (inclusive). Se o valor estiver fora desse intervalo, a temperatura deverá permanecer inalterada.
  • main.rs: Inclua seu módulo de termostato, crie um termostato e demonstre a validação do setter tentando definir várias temperaturas e imprimindo o resultado após cada tentativa.

O setter deve ignorar silenciosamente valores inválidos: nenhuma mensagem de erro, apenas mantenha a temperatura atual inalterada quando alguém tentar defini-la fora do intervalo válido.

Sua saída deve seguir exatamente este formato:

Initial: {temperature}
After setting to {attempted_value}: {temperature}
After setting to {attempted_value}: {temperature}

Por exemplo, se você criar um termostato em 20, tentar defini-lo como 25 (válido) e depois como 50 (inválido), a saída será:

Initial: 20
After setting to 25: 25
After setting to 50: 25

Você receberá três entradas: a temperatura inicial, a primeira temperatura a ser testada e a segunda temperatura a ser testada.

Experimente você mesmo

mod thermostat;

use thermostat::Thermostat;

fn main() {
    // Ler entradas
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let initial_temp: i32 = input1.trim().parse().expect("Invalid number");

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let first_attempt: i32 = input2.trim().parse().expect("Invalid number");

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let second_attempt: i32 = input3.trim().parse().expect("Invalid number");

    // TODO: Crie um termostato com a temperatura inicial

    // TODO: Imprima a temperatura inicial
    // Formato: "Initial: {temperature}"

    // TODO: Tente definir a primeira temperatura e imprima o resultado
    // Format: "After setting to {attempted_value}: {temperature}"

    // TODO: Tente definir a segunda temperatura e imprima o resultado
    // Format: "After setting to {attempted_value}: {temperature}"
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Rust online