Arrays e Structs em Go

Tipo Nome Valor Padrão Observação
pointer Ponteiro nil
array Array 0 Tamanho fixo
slice Slice nil Tipo por referência
map Mapa nil Tipo por referência
struct Struct zero value

Arrays

Para armazenar as notas de matemática de uma turma, criar dezenas de variáveis individuais seria impraticável. A solução é utilizar um array: uma coleção de elementos do mesmo tipo.

Declaração

var notas [10]int

A declaração usa a palavra-chave var, seguida do nome da variável, do tamanho entre colchetes e do tipo. O array notas armazena 10 valores inteiros.

Verificação do tamanho:

var notas [10]int
fmt.Println(cap(notas)) // 10

Ao declarar o array, o Go aloca um bloco contínuo de memória. Cada posição armazena um elemento, e o total de posições define o comprimento.

var tamanho int = 10
var notas [tamanho]int // ERRO: tamanho não é constante

Structs agrupam campos relacionados em uma única entidade:

package main

import "fmt"

func main() {
    // Definição do struct
    type Pessoa struct {
        codigo   int
        nome     string
        idade    int
        cidade   string
    }

    // Inicialização por posição
    aluno := Pessoa{1, "Ana", 21, "São Paulo"}
    fmt.Println(aluno) // {1 Ana 21 São Paulo}

    // Inicialização com campos nomeados
    professor := Pessoa{nome: "Carlos"}
    fmt.Println(professor) // {0 Carlos 0 }

    // Acesso e modificação de campos
    aluno.codigo = 100
    fmt.Println(aluno.codigo)

    // Comparação de structs
    fmt.Println(aluno == professor) // false

    // Atribuição entre structs do mesmo tipo
    var copia Pessoa
    copia = professor
    fmt.Println(copia)
}

Composição com Campos Anônimos

Go permite incorporar tipos sem nome explícito de campo, promovendo seus campos para o escopo da struct externa:

// Base
type SerHumano struct {
    nome  string
    sexo  byte
    idade int
}

// Derivada com composição
type Aluno struct {
    SerHumano // Campo anônimo: todos os campos de SerHumano são acessíveis diretamente
    matricula int
    endereco  string
}

Inicialização de Structs Compositos

// Inicialização completa
a1 := Aluno{SerHumano{"Pedro", 'm', 20}, 123, "RJ"}
fmt.Printf("%+v\n", a1)

// Inicialização parcial com campos nomeados
a2 := Aluno{SerHumano: SerHumano{"Maria", 'f', 22}, matricula: 456}
fmt.Printf("%+v\n", a2)

// Inicialização seletiva do campo anônimo
a3 := Aluno{SerHumano: SerHumano{nome: "João"}, matricula: 789}
fmt.Printf("%+v\n", a3)

Manipulação de Campos Promovidos

var a Aluno

// Acesso direto aos campos promovidos
a.nome = "Pedro"      // equivale a: a.SerHumano.nome = "Pedro"
a.sexo = 'm'
a.idade = 20
a.matricula = 123
a.endereco = "Rio"

fmt.Println(a)

// Atribuição do campo anônimo completo
var b Aluno
b.SerHumano = SerHumano{"Maria", 'f', 21}
b.matricula = 456
b.endereco = "SP"

fmt.Println(b)

Resolução de Nomes Duplicados

Quando campos de mesmo nome existem, a prioridade é do nível mais externo:

type SerHumano struct {
    nome  string
    idade int
}

type Funcionario struct {
    SerHumano
    cargo string
    nome  string // Colisão de nomes
}

func main() {
    var f Funcionario
    
    f.nome = "Silva"           // Atribui a Funcionario.nome
    f.SerHumano.nome = "Sousa" // Atribui a SerHumano.nome explicitamente
    
    fmt.Printf("%+v\n", f)
}

Tipos Anônimos Diversos

Tipos Básicos e Customizados

type TextoCustom string

type Dados struct {
    SerHumano    // Struct anônimo
    int          // Tipo básico anônimo
    TextoCustom  // Tipo customizado anônimo
}

func main() {
    d := Dados{SerHumano{"Luiz", 'm', 30}, 100, "SP"}
    
    // Acesso direto
    fmt.Printf("%s, %d, %s\n", d.nome, d.int, d.TextoCustom)
}

Ponetiro para Struct Anônimo

type Empregado struct {
    *SerHumano  // Ponteiro para struct anônimo
    registro    int
    setor       string
}

func main() {
    // Inicialização com ponteiro literal
    e1 := Empregado{&SerHumano{"Fernanda", 'f', 28}, 1000, "TI"}
    fmt.Printf("%+v\n", e1)
    
    // Inicialização com alocação dinâmica
    var e2 Empregado
    e2.SerHumano = new(SerHumano)
    e2.nome = "Ricardo"
    e2.idade = 35
    e2.registro = 1001
    e2.setor = "RH"
    
    fmt.Println(e2.nome, e2.idade, e2.registro)
}

Structs com Mutex para Concorrência

package main

import (
    "fmt"
    "sync"
)

type CadastroIdades struct {
    valores map[string]int
    sync.RWMutex
}

func (c *CadastroIdades) Definir(nome string, idade int) {
    c.Lock()
    defer c.Unlock()
    c.valores[nome] = idade
}

func (c *CadastroIdades) Consultar(nome string) int {
    c.RLock()
    defer c.RUnlock()
    if idade, existe := c.valores[nome]; existe {
        return idade
    }
    return -1
}

func main() {
    base := make(map[string]int)
    base["sistema"] = 5

    registro := CadastroIdades{valores: base}
    registro.Definir("teste", 25)

    fmt.Println(registro.Consultar("sistema")) // 5
    fmt.Println(registro.Consultar("teste"))   // 25
    fmt.Println(registro.Consultar("inexistente")) // -1
}

Tags: go Golang Array struct Mutex

Publicado em 10-5 05:11