Pular para o conteúdo principal

victorstein.dev

2/100 Dias de Golang - Tipos Compostos - Arrays

Table of Contents

# Tipos Compostos

No capítulo 4 do livro A Linguagem de Programação Go[1] é feito uma analogia muito boa sobre tipos no Golang. Os tipos básico, são como os átomos e os tipos compostos são como as moléculas - uma combinação de vários átomos. Nesse post vamos mergulhar no tipo composto array.

# Arrays

Um array é uma sequência com um tamanho pré definido de um tipo específico. No Go, o tamanho do array faz parte do tipo Devido a essa “limitação” de ter um tamanho pré determinado, sendo assim arrays são pouco usados em Go.

## Declaração de Arrays

A declaração de um array é feita da seguinte forma:

var x [10]int

Isso cria um array de 10 posições, como não foi definido nenhum valor para as posições, o valor default do tipo int é o 0. Podemos criar um array com valores definidos:

var x [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

## “Matrizes”

Go possui somente array unidimensionais, não existe um tipo de matriz, mas podemos simular esse comportamento criando um array dentro de outro array.

var x [3][4]byte

Aqui estamos dizendo que temos um array de 3 elementos, e cada elemento é um array de 4 elementos, do tipo byte.

## Alocação na memória

Na memória arrays são armazenados de forma contígua, o que torna a leitura e escrita mais rápida. Veja esse exemplo onde é exibido a posição de memória de cada elemento do array:

var x [3][4]byte

for i := 0; i < 3; i++ {
   for j := 0; j < 4; j++ {
      fmt.Printf("x[%d][%d] -> %p\n", i, j, &x[i][j])
      // x[0][0] -> 0xc000098040
      // x[0][1] -> 0xc000098041
      // x[0][2] -> 0xc000098042
      // x[0][3] -> 0xc000098043
      // x[1][0] -> 0xc000098044
      // x[1][1] -> 0xc000098045
      // x[1][2] -> 0xc000098046
      // x[1][3] -> 0xc000098047
      // x[2][0] -> 0xc000098048
      // x[2][1] -> 0xc000098049
      // x[2][2] -> 0xc00009804a
      // x[2][3] -> 0xc00009804b
   }
}

Uma curiosidade é que Go aloca na memória os valores seguindo a regra de Row-major order, que significa que os elementos são armazenados linha por linha. Em outras linguagem, como Julia o padrão é Column-major order, isso favorece desempenho em algumas operações com matrizes. Veja como fica a alocação de uma matriz 3x4 em Julia:

Posição de memória de cada elemento:
Elemento (1, 1) -> @0x00007c2ffa4f0a20
Elemento (1, 2) -> @0x00007c2ffa4f0a38
Elemento (1, 3) -> @0x00007c2ffa4f0a50
Elemento (1, 4) -> @0x00007c2ffa4f0a68
Elemento (2, 1) -> @0x00007c2ffa4f0a28
Elemento (2, 2) -> @0x00007c2ffa4f0a40
Elemento (2, 3) -> @0x00007c2ffa4f0a58
Elemento (2, 4) -> @0x00007c2ffa4f0a70
Elemento (3, 1) -> @0x00007c2ffa4f0a30
Elemento (3, 2) -> @0x00007c2ffa4f0a48
Elemento (3, 3) -> @0x00007c2ffa4f0a60
Elemento (3, 4) -> @0x00007c2ffa4f0a78

O elemento (1,1) está na posição 0x00007c2ffa4f0a20 e o elemento na próxima posição de memória é o (2,1) 0x00007c2ffa4f0a28.

## Tamanho e Capacidade

Go tem duas funções muito úteis, len e cap. A função len retorna o tamanho e a função cap retorna a capacidade. No caso de arrays a capacidade é o tamanho do array. Veja o exemplo abaixo:

var x [10]int
fmt.Println("Tamanho do array x:", len(x)) // 10
fmt.Println("Capacidade do array x:", cap(x)) // 10

## Iterando sobre Arrays

Podemos iterar sobre arrays de várias formas, podemos usar um for mais C-Style:

var x [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

for i := 0; i < len(x); i++ {
	fmt.Println(x[i])
}

Ou um range:

var x [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

for index, value := range x {
	fmt.Println(index, value)
}

## Comparação de arrays

Arrays podem ser comparados com o operador ==, mas somente arrays do mesmo tipo e tamanho podem ser comparados. Lembre que o compilador Go considera o tamanho do array como parte do tipo.

var x [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var y [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

fmt.Println(x == y) // true

var z [10]int = [10]int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
fmt.Println(x == z) // false

var w [5]int = [5]int{1, 2, 3, 4, 5}
fmt.Println(x == w) // false

# Referências

  1. Capítulo 4 - Tipos Compostos A Linguagem de Programação Go
  2. Chapter 3 - Composite Types Learning Go: An Idiomatic Approach to Real-World Go Programming