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 Pessoa deve ter Nome string e Idade int.
  • A função adicionar deve receber *[]*Pessoa e usar new(Pessoa) para criar cada pessoa.
  • A função aniversariar deve receber []*Pessoa e 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

  1. Definimos a struct Pessoa com Nome e Idade.
  2. adicionar recebe fila *[]*Pessoa, um ponteiro para a slice, para poder modificar a slice original.
  3. Dentro de adicionar, p := new(Pessoa) aloca uma Pessoa zerada e devolve *Pessoa.
  4. Atribuímos p.Nome e p.Idade (desreferenciação automática).
  5. *fila = append(*fila, p) desreferencia o ponteiro para slice, adiciona o novo ponteiro e atualiza a slice original.
  6. aniversariar recebe []*Pessoa e itera sobre os ponteiros; p.Idade++ modifica a Pessoa apontada.
  7. No main, chamamos adicionar(&fila, ...) passando o endereço da slice.
  8. Depois de aniversariar(fila), imprimimos cada pessoa com fmt.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 []*Pessoa para adicionar e fazer fila = append(fila, p): a slice local é alterada, mas a do main nã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 de new(Pessoa) e depois append(fila, &p): &p aponta para a variável local, que pode ser reutilizada em iterações, causando bugs.
  • Em aniversariar, se fila fosse []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