Exemplo

#[derive(Debug)]
struct Corrida {
    nome: String,
    voltas: Vec<i32>,
}

impl Corrida {
    fn new(nome: &str) -> Corrida {  // Sem receptor, método eståtico
        Corrida { nome: String::from(nome), voltas: Vec::new() }
    }

    fn adicionar_volta(&mut self, volta: i32) {  // EmprĂ©stimo Ășnico com acesso de leitura e escrita em self
        self.voltas.push(volta);
    }

    fn imprimir_voltas(&self) {  // Empréstimo compartilhado com acesso apenas de leitura em self
        println!("Registrou {} voltas para {}:", self.voltas.len(), self.nome);
        for (idx, volta) in self.voltas.iter().enumerate() {
            println!("Volta {idx}: {volta} seg");
        }
    }

    fn encerrar(self) {  // Propriedade exclusiva de self
        let total = self.voltas.iter().sum::<i32>();
        println!("Corrida {} foi encerrada, tempo de voltas total: {}", self.nome, total);
    }
}

fn main() {
    let mut corrida = Corrida::new("Monaco Grand Prix");
    corrida.adicionar_volta(70);
    corrida.adicionar_volta(68);
    corrida.imprimir_voltas();
    corrida.adicionar_volta(71);
    corrida.imprimir_voltas();
    corrida.encerrar();
    // corrida.adicionar_volta(42);
}

Pontos Chave:

  • Todos os quatro mĂ©todos aqui usam um receptor de mĂ©todo diferente.
    • VocĂȘ pode apontar como isso muda o que a função pode fazer com os valores das variĂĄveis e se/como ela pode ser usada novamente na main.
    • VocĂȘ pode mostrar o erro que aparece ao tentar chamar encerrar duas vezes.
  • Observe que, embora os receptores do mĂ©todo sejam diferentes, as funçÔes nĂŁo estĂĄticas sĂŁo chamadas da mesma maneira no corpo principal. Rust permite referenciar e desreferenciar automaticamente ao chamar mĂ©todos. Rust adiciona automaticamente &, *, muts para que esse objeto corresponda Ă  assinatura do mĂ©todo.
  • VocĂȘ pode apontar que imprimir_voltas estĂĄ usando um vetor e iterando sobre ele. Descreveremos os vetores com mais detalhes Ă  tarde.