GO - Tipos compostos

Array

Um array é uma sequencia de tamanho fixo de zero ou mais elements

var q [3]int = [3]int{1,2,3}
q := [...]int{1,2,3} // com a reticencia o tamano será determinado pela quantidade de inicializadores

O tamanho de um array faz parte do seu tipo

q := [3]int{1,2,3}
q = [4]int{1,2,3,4} // erro de compilação: não é permitido atribuir [4]int a [3]int

Arrays são inflexiveis

Fatias (slices)

Uma fatia representa um sequencia de tamanho variavel cujo elementos tem o mesmo tipo. Uma fatia tem tres elementos:

Uma fatia pode ser extendia além de seu tamanho, mas não além da sua capacidade. Como uma fatia contém um ponteiro para o array subjacente isso permite que uma função modifique os elementos do array subjacete

Make

make([]T, len)
make([]T, len, cap) // mesmo que make ([]T, cap)[:len]

Função append

u := [11]int{}
y := u[:10]
fmt.Println(u, y)
z := append(y, 2, 3)

Esta função vai extender o slice caso a capacidade do array subjacente seja suficiente para encaixar os novos elementos, caso contrário é criado um novo array subjacente com capacidade suficiente para encaixar os novos elementos.

Mapas

É uma referência a uma tabela hash, escrito como map[K]V Requisitos:

ages := make(map[string]int)
deletes(ages, "alice") // remove o elemento com a chave "alice"
import (
	"fmt"
)

func main() {
	m := map[string]int{"originalMap": 1}
	reallocate(m)
	fmt.Println(m) // prints originalMap: 1
	reallocatePtrWrong(&m)
	fmt.Println(m) // prints originalMap: 1
	reallocatePtr(&m)
	fmt.Println(m) // prints overrideMap: 1
	extend(m)
	fmt.Println(m) // prints overrideMap: 1 extended: 2
}

func reallocate(m map[string]int) {
	// Orginal value of m outside function not changed.
	m = map[string]int{"overrideMap": 1}
}

func extend(m map[string]int) {
	// Chaging m without realocation works, and don't need a pointer.
	m["extended"] = 2
}

func reallocatePtrWrong(m *map[string]int) {
	// Realocate using pointer don't become visible outisde if we
	// only update the poniter value.
	m = &map[string]int{"overrideMap": 1}
}

func reallocatePtr(m *map[string]int) {
	// Realocate using pointer work if we do it right.
	*m = map[string]int{"overrideMap": 1}
}

Estruturas

A estrutura é um tipo de dado que agregra diferentes tipos em uma unica entidade.

package p
type T struct{a, b int}
package p
va _ = p.T{a: 1, b:2 } // erro de compilação: não é possivel referencias a, b
va _ = p.T{1, 2} // erro de compilação: não é possivel referencias a, b

Campos anônimos

type Circle struct {
	Point
	Radius int
}

Com o campo anônimo podemos acessar várivaeis correspondentes ao tipo anonimo diretamente na raiz:

var c Circle
c.X = 10 // se não fosse anonimo precisariamos acessar assim x.Point.X = 10
c.Y = 10

Porém para popular os campos na inicialização precisamos declarar os tipos especificados

c := Circle{Point{x: 1, y: 2}, 10}
pp := &Point{1, 2}