Desafio Go
Fila de pessoas com ponteiros e new
Enunciado
Implemente uma fila simples de pessoas usando uma slice de ponteiros para a struct Pessoa (campos Nome e Idade). Crie funções adicionar(fila *[]*Pessoa, nome string, idade int) que usa new(Pessoa) para alocar e adiciona à fila, e aniversariar(fila []*Pessoa) que incrementa a idade de todas as pessoas. No main, adicione duas pessoas, chame aniversariar e imprima nome e idade de cada uma.
Requisitos
- A struct
Pessoadeve terNome stringeIdade int. - A função
adicionardeve receber*[]*Pessoae usarnew(Pessoa)para criar cada pessoa. - A função
aniversariardeve receber[]*Pessoae incrementar a idade de cada uma. - A saída deve listar cada pessoa no formato
Nome: X, Idade: Y.
Código inicial
package main
import "fmt"
type Pessoa struct {
Nome string
Idade int
}
// adicionar cria uma nova Pessoa com new e a insere na fila.
func adicionar(fila *[]*Pessoa, nome string, idade int) {
// complete aqui
}
// aniversariar incrementa a idade de todas as pessoas da fila.
func aniversariar(fila []*Pessoa) {
// complete aqui
}
func main() {
var fila []*Pessoa
adicionar(&fila, "Ana", 30)
adicionar(&fila, "Bruno", 25)
aniversariar(fila)
for _, p := range fila {
fmt.Printf("%s: %d, Idade: %d\n", p.Nome, p.Idade, p.Idade)
}
}
Saída esperada
Ana: 31, Idade: 31
Bruno: 26, Idade: 26
Ver dica
Em adicionar, use p := new(Pessoa), defina os campos e faça *fila = append(*fila, p). Em aniversariar, use p.Idade++.
Mostrar solução
package main
import "fmt"
type Pessoa struct {
Nome string
Idade int
}
// adicionar cria uma nova Pessoa com new e a insere na fila.
func adicionar(fila *[]*Pessoa, nome string, idade int) {
p := new(Pessoa) // aloca uma Pessoa zerada e retorna *Pessoa
p.Nome = nome
p.Idade = idade
*fila = append(*fila, p) // desreferencia a slice para modificar a original
}
// aniversariar incrementa a idade de todas as pessoas da fila.
func aniversariar(fila []*Pessoa) {
for _, p := range fila {
p.Idade++ // p é *Pessoa, modifica a Pessoa original
}
}
func main() {
var fila []*Pessoa
adicionar(&fila, "Ana", 30)
adicionar(&fila, "Bruno", 25)
aniversariar(fila)
for _, p := range fila {
fmt.Printf("%s: %d, Idade: %d\n", p.Nome, p.Idade, p.Idade)
}
}
Passo a passo
- Definimos a struct
PessoacomNomeeIdade. adicionarrecebefila *[]*Pessoa, um ponteiro para a slice, para poder modificar a slice original.- Dentro de
adicionar,p := new(Pessoa)aloca umaPessoazerada e devolve*Pessoa. - Atribuímos
p.Nomeep.Idade(desreferenciação automática). *fila = append(*fila, p)desreferencia o ponteiro para slice, adiciona o novo ponteiro e atualiza a slice original.aniversariarrecebe[]*Pessoae itera sobre os ponteiros;p.Idade++modifica aPessoaapontada.- No
main, chamamosadicionar(&fila, ...)passando o endereço da slice. - Depois de
aniversariar(fila), imprimimos cada pessoa comfmt.Printf.
Por que funciona
A slice é um descritor (ponteiro, len, cap). Para alterar a slice original (adicionar elementos), passamos *[]*Pessoa e usamos *fila = append(...). Já os elementos são *Pessoa, então aniversariar pode modificar as structs originais sem precisar de ponteiro para slice. new(Pessoa) garante que cada pessoa tenha endereço próprio e não seja copiada.
Erros comuns
- Passar
fila []*Pessoaparaadicionare fazerfila = append(fila, p): a slice local é alterada, mas a domainnão vê a mudança. - Esquecer o
*em*fila = append(...):fila = append(fila, p)compila, mas não atualiza a slice original. - Usar
p := Pessoa{}em vez denew(Pessoa)e depoisappend(fila, &p):&paponta para a variável local, que pode ser reutilizada em iterações, causando bugs. - Em
aniversariar, sefilafosse[]Pessoa(valores),p.Idade++modificaria uma cópia e não a original.
Outra forma de resolver
Usar append diretamente no main sem função adicionar:
fila = append(fila, &Pessoa{Nome: "Ana", Idade: 30})
É mais conciso, mas menos modular. A função adicionar ajuda a encapsular a criação com new.
Saída esperada
Ana: 31, Idade: 31
Bruno: 26, Idade: 26