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
- Capítulo 4 - Tipos Compostos A Linguagem de Programação Go
- Chapter 3 - Composite Types Learning Go: An Idiomatic Approach to Real-World Go Programming