Exemplo
#[derive(Debug)] struct Race { name: String, laps: Vec<i32>, } impl Race { fn new(name: &str) -> Race { // Sem receptor, método estático Race { name: String::from(name), laps: Vec::new() } } fn add_lap(&mut self, lap: i32) { // Empréstimo único com acesso de leitura e escrita em self self.laps.push(lap); } fn print_laps(&self) { // Empréstimo compartilhado com acesso apenas de leitura em self println!("Registrou {} voltas para {}:", self.laps.len(), self.name); for (idx, lap) in self.laps.iter().enumerate() { println!("Volta {idx}: {lap} seg"); } } fn finish(self) { // Propriedade exclusiva de self let total = self.laps.iter().sum::<i32>(); println!("Corrida {} foi encerrada, tempo de voltas total: {}", self.name, total); } } fn main() { let mut race = Race::new("Monaco Grand Prix"); race.add_lap(70); race.add_lap(68); race.print_laps(); race.add_lap(71); race.print_laps(); race.finish(); // race.add_lap(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.
- 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
- 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.