Muitas vezes é útil agrupar uma coleção de itens e tratar esses grupos como unidades. Em Rust, chamamos esse grupo de struct, e cada item é um dos campos da struct. Uma struct define o conjunto geral de campos disponíveis, mas um exemplo específico de struct é chamado de instância.
Além disso, structs podem ter métodos definidos nelas, e esses métodos têm acesso aos campos. Nesse caso, a própria struct é chamada de self. Quando um método usa &mut self, os campos podem ser alterados, ou mutados. Quando um método usa &self, os campos não podem ser alterados: eles são imutáveis. Controlar a mutabilidade ajuda o borrow checker a garantir que classes inteiras de bugs de concorrência simplesmente não aconteçam em Rust.
Neste exercício, você vai implementar dois tipos de métodos em uma struct. O primeiro tipo é geralmente conhecido como getters: eles expõem os campos da struct para o mundo, sem deixar que ninguém mais mute esse valor. Em Rust, por convenção, esses métodos têm o mesmo nome do campo que expõem, ou seja, se tivermos um método getter que busca um campo da struct chamado name, o método simplesmente se chamaria name().
Você também vai implementar métodos de outro tipo, geralmente conhecidos como setters. Eles mudam o valor do campo. Setters não são muito comuns em Rust (se um campo pode ser modificado livremente, é mais comum simplesmente torná-lo público), mas são úteis se atualizar o campo deve ter efeitos colaterais, ou para controle de acesso: um setter marcado como pub(crate) permite que outros módulos dentro da mesma crate atualizem um campo privado, que não pode ser afetado pelo mundo externo.
As structs vêm em três variedades: structs com campos nomeados, structs de tupla e structs unitárias. Neste exercício de conceito, vamos explorar a primeira variante: structs com campos nomeados.
As structs são definidas com a palavra-chave struct, seguida do nome do tipo que a struct descreve, com inicial maiúscula:
struct Item {}
Outros tipos são então trazidos para o corpo da struct como campos da struct, cada um com seu próprio tipo:
struct Item {
name: String,
weight: f32,
worth: u32,
}
Por fim, métodos podem ser definidos em structs dentro de um bloco impl:
impl Item {
// initializes and returns a new instance of our Item struct
fn new() -> Self {
todo!()
}
}
Com essa breve introdução à sintaxe das structs, dê uma olhada nas instruções deste exercício!
Você está trabalhando na implementação de um sistema de monitoramento de saúde. Como parte disso, você precisa acompanhar as estatísticas de saúde dos usuários.
Você vai começar com algumas funções esboçadas em um bloco impl, além da seguinte definição de struct:
pub struct User {
name: String,
age: u32,
weight: f32,
}
Seu objetivo é implementar os métodos esboçados do User struct definido no bloco impl.
Por exemplo, o método new deve retornar uma instância do struct User com os valores de nome, idade e peso especificados.
let mut bob = User::new(String::from("Bob"), 32, 155.2);
// Returns: a User with name "Bob", age 32, and weight 155.2
O método weight deve retornar o peso do User.
bob.weight();
// Returns: 155.2
O método set_age deve definir a idade do User.
bob.set_age(33);
// Updates Bob's age to 33; happy birthday Bob!
Divirta-se!
Crie sua conta no Exercism para aprender e dominar Rust com 99 exercícios e mentoria humana de verdade, tudo de graça.