💻 Exemplos: Capítulo 09: Structs, Tuple Structs e Blocos impl

Especialização em Sistemas com Rust • Demonstrações Práticas Compiláveis


🎯 Objetivo dos Exemplos

Demonstrar a modelagem de entidades de domínio e componentes de sistema utilizando Classic Structs, Tuple Structs e Unit Structs, definindo funções associadas (construtores new), métodos com leitura imutável (&self) e métodos com mutação in-place (&mut self).


1. Código Fonte Completo (src/main.rs)

//! Modelagem de Dados com Structs e Métodos com Blocos impl em Rust

// 1. Classic Struct com campos nomeados
#[derive(Debug, Clone)]
struct ServidorCluster {
    hostname: String,
    ip_addr: String,
    porta: u16,
    conexoes_ativas: u32,
    ativo: bool,
}

// 2. Tuple Struct para tipos nominais fortes (Newtype Pattern)
#[derive(Debug, Clone, Copy)]
struct PortaRede(u16);

#[derive(Debug, Clone, Copy)]
struct Milissegundos(u64);

// 3. Unit Struct para marcadores de estado sem consumo de memória (Zero-Sized Type)
#[derive(Debug)]
struct ProtocoloSeguroTLS;

// Bloco de Implementação (impl) da Struct
impl ServidorCluster {
    // Função Associada (Construtor idiomático 'new')
    // Não recebe 'self', atua como método de fábrica
    fn new(hostname: &str, ip: &str, porta: u16) -> Self {
        Self {
            hostname: String::from(hostname),
            ip_addr: String::from(ip),
            porta,
            conexoes_ativas: 0,
            ativo: true,
        }
    }

    // Método de leitura imutável (&self)
    fn obter_endereco_completo(&self) -> String {
        format!("{}:{}", self.ip_addr, self.porta)
    }

    // Método de mutação in-place (&mut self)
    fn registrar_conexao(&mut self) -> u32 {
        self.conexoes_ativas += 1;
        self.conexoes_ativas
    }

    fn encerrar_conexao(&mut self) {
        if self.conexoes_ativas > 0 {
            self.conexoes_ativas -= 1;
        }
    }

    // Método que assume o ownership e consome a instância (self por valor)
    fn desativar(mut self) {
        self.ativo = false;
        println!("  [ALERTA] Servidor '{}' foi permanentemente desativado.", self.hostname);
        // 'self' sai de escopo e é destruído aqui
    }
}

fn main() {
    println!("=== MODELAGEM DE SISTEMAS COM STRUCTS E IMPL ===");

    // 1. Instanciando via Construtor Associado
    let mut srv_principal = ServidorCluster::new("app-cluster-node-01", "192.168.1.50", 8080);
    println!("Servidor instanciado: {:?}", srv_principal);
    println!("Endereço de rede: {}", srv_principal.obter_endereco_completo());

    // 2. Invocando métodos de mutação (&mut self)
    srv_principal.registrar_conexao();
    srv_principal.registrar_conexao();
    srv_principal.registrar_conexao();
    println!("Conexões após tráfego de rede: {}", srv_principal.conexoes_ativas);

    srv_principal.encerrar_conexao();
    println!("Conexões após desconexão de cliente: {}", srv_principal.conexoes_ativas);

    // 3. Uso do Newtype Pattern com Tuple Structs
    let porta_ssh = PortaRede(22);
    let timeout = Milissegundos(5000);
    println!("\nConfiguração de Conexão Segura:");
    println!("Porta SSH: {} | Timeout de Resposta: {} ms", porta_ssh.0, timeout.0);

    // 4. Unit Struct (Tamanho zero na memória - ZST)
    let _marcador = ProtocoloSeguroTLS;
    println!("Tamanho em bytes da Unit Struct na memória: {} bytes", std::mem::size_of::<ProtocoloSeguroTLS>());

    // 5. Consumo de Instância (Taking Ownership)
    println!("\nDescomissionando o nó do cluster:");
    srv_principal.desativar();
    // srv_principal não pode mais ser acessado aqui!
}

2. Saída Esperada no Terminal

=== MODELAGEM DE SISTEMAS COM STRUCTS E IMPL ===
Servidor instanciado: ServidorCluster { hostname: "app-cluster-node-01", ip_addr: "192.168.1.50", porta: 8080, conexoes_ativas: 0, ativo: true }
Endereço de rede: 192.168.1.50:8080
Conexões após tráfego de rede: 3
Conexões após desconexão de cliente: 2

Configuração de Conexão Segura:
Porta SSH: 22 | Timeout de Resposta: 5000 ms
Tamanho em bytes da Unit Struct na memória: 0 bytes

Descomissionando o nó do cluster:
  [ALERTA] Servidor 'app-cluster-node-01' foi permanentemente desativado.