Structs Aninhadas
Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 16 de 107.
Uma struct aninhada é uma struct que contém outra struct nomeada como um de seus campos. Isso permite modelar dados complexos e hierárquicos compondo tipos menores e reutilizáveis.
type Address struct {
Street string
City string
ZIP string
}
type Person struct {
Name string
Age int
Address Address // struct aninhada
}Para acessar campos em uma struct aninhada, encadeie os nomes dos campos com pontos.
p := Person{
Name: "Alice",
Age: 30,
Address: Address{
Street: "123 Main St",
City: "Boston",
ZIP: "02101",
},
}
fmt.Println(p.Address.City) // BostonO aninhamento promove a reutilização de código. O tipo Address pode ser usado em múltiplas structs como Person, Company ou Order sem duplicar campos. Essa abordagem reflete relacionamentos do mundo real onde entidades contêm outras entidades.
type Company struct {
Name string
Employees int
Address Address // mesmo tipo Address reutilizado
}Você pode aninhar structs em vários níveis de profundidade, embora manter as hierarquias rasas melhore a legibilidade. Structs aninhadas são fundamentais para construir modelos de dados orientados a objetos em Go.
Desafio
FácilVamos criar um sistema de gerenciamento de funcionários que demonstra como structs aninhadas ajudam a modelar hierarquias do mundo real. Você criará uma estrutura na qual os funcionários pertencem a departamentos, e os departamentos têm informações de localização.
Você organizará seu código em dois arquivos:
models.go: Defina três structs que trabalham juntas:Locationcom os camposBuilding(string) eFloor(int)DepartmentcomName(string) e um campoLocationaninhadoEmployeecomID(int),Name(string) e um campoDepartmentaninhado
main.go: Leia as informações do funcionário da entrada, crie um Employee com structs devidamente aninhadas e exiba o perfil completo do funcionário acessando os campos por meio da estrutura aninhada.
As seguintes entradas serão fornecidas:
- Linha 1: ID do funcionário (inteiro)
- Linha 2: Nome do funcionário
- Linha 3: Nome do departamento
- Linha 4: Nome do prédio
- Linha 5: Número do andar (inteiro)
Formato da saída:
Employee: [Name] (ID: [ID])
Department: [DepartmentName]
Location: [Building], Floor [Floor]Por exemplo, dadas as entradas 101, Alice Chen, Engineering, Tower A e 5, sua saída deverá ser:
Employee: Alice Chen (ID: 101)
Department: Engineering
Location: Tower A, Floor 5Acesse os campos aninhados usando a notação de ponto para encadear o acesso pela hierarquia de structs (por exemplo, employee.Department.Location.Building).
Experimente você mesmo
package main
import "fmt"
func main() {
// Ler informações do funcionário
var id int
var name string
var deptName string
var building string
var floor int
fmt.Scanln(&id)
fmt.Scanln(&name)
fmt.Scanln(&deptName)
fmt.Scanln(&building)
fmt.Scanln(&floor)
// TODO: Criar um Employee com structs devidamente aninhadas
// Use as structs Location, Department e Employee de models.go
// Inicialize todos os campos aninhados com os valores de entrada
// TODO: Imprimir o perfil do funcionário usando o formato:
// Employee: [Name] (ID: [ID])
// Department: [DepartmentName]
// Location: [Building], Floor [Floor]
// Acesse campos aninhados usando a notação de ponto (ex: employee.Department.Location.Building)
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP em Go
Arquivos ExternosWorkspace e Módulos do GoPacotes e ImportsNomes Exportados vs. Não ExportadosIntrodução à OOP em GoStructs como ClassesDefinindo Métodos em StructsReceptores de Ponteiro vs. de ValorInicialização de StructsFunções ConstrutorasRecapitulação — Calculadora Simples4Interfaces
Introdução às InterfacesImplementação ImplícitaInterface como ContratoInterface Vazia (any)Asserção de TipoSwitch de TipoComposição de InterfacesInterfaces Stringer e ErrorRecapitulação - Calculadora de Formas7Encapsulamento
Campos Exportados vs. Não ExportadosEncapsulamento no Nível de PacoteMétodos Getters e SettersOcultação de Informações em GoRecapitulação - Registros de Alunos10Genéricos (Go 1.18+)
Introdução aos genéricosParâmetros de tipoRestrições de tipoStructs genéricasAlternativa para métodos genéricosRecapitulação - Coleção genérica13Padrões de Projeto — Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão Abstract FactoryPadrão ObserverPadrão Strategy2Tipos e Structs em Profundidade
Tipos Básicos e CompostosDefinições de Tipos PersonalizadosTags de StructStructs AnônimasStructs AninhadasValores Zero e PadrõesRecapitulação - Livro de Contatos5Composição em vez de herança
Por que Go não tem herançaNoções básicas de incorporação de structsPromoção de métodosIncorporação de várias structsIncorporação vs agregaçãoOcultação de métodos incorporadosRecapitulação - Hierarquia de funcionários8Tratamento de Erros e OOP
A interface errorTipos de Erro PersonalizadosEncapsulamento de Erros (fmt.Errorf)Erros Sentinelaerrors.Is() e errors.As()Panic, Defer e RecoverRecapitulação - Analisador de Arquivos3Ponteiros e Memória
Fundamentos de Ponteiros em GoPonteiros para StructsPassagem por Valor vs. ReferênciaA Função new()Coleta de Lixo em GoRecapitulação - Construtor de Lista Ligada6Polimorfismo em Go
Polimorfismo via InterfacesDuck Typing em GoRegras de Satisfação de InterfacesColeções PolimórficasInjeção de DependênciasRecapitulação - Processador de Pagamentos9Concorrência e OOP
Fundamentos de GoroutinesCanais e comunicaçãoCanais com e sem bufferInstrução selectsync.Mutex e sync.RWMutexsync.WaitGroupDesign de structs thread-safeRevisão - Worker PoolPratique por conta própria: Compilador de Go online