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
Uma fatia representa um sequencia de tamanho variavel cujo elementos tem o mesmo tipo. Uma fatia tem tres elementos:
len
- retorna o tamanhocap
- retorna a capacidadeUma 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([]T, len)
make([]T, len, cap) // mesmo que make ([]T, cap)[:len]
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.
É uma referência a uma tabela hash, escrito como map[K]V
Requisitos:
K
deve ser comparavelages := make(map[string]int)
deletes(ages, "alice") // remove o elemento com a chave "alice"
ages["carol"] = 21 // pânico: atribuição a uma entrada em um mapa nil
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}
}
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
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}