Médio Rust
Struct com referência e método
Enunciado
Crie uma struct Config<'a> que armazena nome: &'a str e valor: &'a str. Implemente um método resumo(&self) -> String que retorna uma String formatada como "{nome}={valor}". No main, instancie com literais e imprima o resumo.
Requisitos
- A struct deve ter um parâmetro de lifetime
'a. - O método
resumodeve retornarString(não referência). - O
maindeve criar uma instância e imprimir o resultado.
Código inicial
struct Config<'a> {
nome: &'a str,
valor: &'a str,
}
impl<'a> Config<'a> {
fn resumo(&self) -> String {
// implemente
}
}
fn main() {
// crie e imprima
}
Saída esperada
debug=true
Ver dica
Use format!("{}={}", self.nome, self.valor).
Mostrar solução
// Struct que guarda referências: precisa de lifetime explícito.
struct Config<'a> {
nome: &'a str,
valor: &'a str,
}
impl<'a> Config<'a> {
// Retorna uma String nova, então não precisa de lifetime no retorno.
fn resumo(&self) -> String {
format!("{}={}", self.nome, self.valor)
}
}
fn main() {
let cfg = Config { nome: "debug", valor: "true" };
println!("{}", cfg.resumo());
}
Passo a passo
- Declaramos
struct Config<'a>com dois campos&'a str. O lifetime'aindica que a struct não pode viver mais que as strings referenciadas. - No
impl<'a> Config<'a>, repetimos o parâmetro de lifetime para implementar métodos nessa struct. - O método
resumo(&self)recebe&selfe retornaString, um tipo próprio que não empresta dados. - Usamos
format!para construir a string no formatonome=valor. - No
main, criamoscfgcom literais'static, então a struct é válida durante todo omain. - Imprimimos o resultado de
cfg.resumo().
Por que funciona
A struct armazena referências, então o compilador exige que o tempo de vida dessas referências seja declarado. Como resumo cria uma nova String, não há necessidade de anotar o retorno com lifetime. O método &self tem elisão automática: o retorno (se fosse referência) estaria ligado ao lifetime de &self.
Erros comuns
- Esquecer o lifetime na struct:
struct Config { nome: &str, valor: &str }gera erromissing lifetime specifier. - Tentar retornar
&strderesumosem lifetime adequado:fn resumo(&self) -> &strfuncionaria com elisão, mas retornaria parte dos dados; o enunciado pedeString. - Criar a struct com
Stringtemporária e tentar guardar referência:let cfg = Config { nome: &String::from("a"), valor: "b" };dá erro porque aStringtemporária é destruída no fim da instrução.
Outra forma de resolver
Se você não quiser se preocupar com lifetimes, pode usar String nos campos:
struct Config {
nome: String,
valor: String,
}
Isso simplifica o código, mas aloca memória. Prefira referências quando os dados já existem em outro lugar.
Saída esperada
debug=true