Slices

Slices #

// _Slices_ é um importante tipo de dado em Go,
// oferecendo uma interface mais completa do que
// arrays para lidar com sequências.

package main

import "fmt"

func main() {

	// Diferente de arrays, slices são tipados apenas com
	// tipo dos elementos que armazenará (sem um tamanho).
	// Para criar um slice vazio, com tamanho não zero,
	// deve-se usar o comando nativo `make`. Aqui é feito
	// um slice de `string`, com tamanho 3
	// (inicialmente com valor padrão zero).
	s := make([]string, 3)
	fmt.Println("vazio:", s)

	// Para alterar os valores de um slice e seleciná-los,
	// faz-se da mesma forma que com array.
	s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	fmt.Println("exibe slice:", s)
	fmt.Println("valor índice 2:", s[2])

	// `len` retorna o tamanho de slices, da mesma forma
	// que com arrays.
	fmt.Println("len:", len(s))

	// Em adição a estas operações básicas, slices
	// suportam muitas outras que as fazem mais úteis do que
	// arrays. Uma delas é a função nativa `append`, que
	// retorna a slice contendo um ou mais novos valores.
	// Note que é preciso aceitar o valor retornado da função
	// `append` para ter a slice atualizada.
	s = append(s, "d")
	s = append(s, "e", "f")
	fmt.Println("slice com acréscimo:", s)

	// Slices também podem ser copiadas com `copy`. Aqui
	// é criado uma slice vazia `c` do mesmo tamanho da
	// slice `s`. Então, a slice `s` é copiada para `c`.
	c := make([]string, len(s))
	copy(c, s)
	fmt.Println("slice copiada:", c)

	// Slices suportam um operador "slice" com a sintaxe
	// `slice[índiceBaixo:índiceAlto]`. Por exemplo, o
	// comando a seguir seleciona os elementos da slice
	// de índices 2, 3 e 4; ou `s[2]`, `s[3]`, e `s[4]`.
	l := s[2:5]
	fmt.Println("slice 1:", l)

	// Já este, "fatia" o slice `s` até o
	// índice 5 (não incluso) ou `s[5]`.
	l = s[:5]
	fmt.Println("slice 2:", l)

	// E este, "fatia" o slices `s` a partir do
	// índice 2 (incluso) ou `s[2]`.
	l = s[2:]
	fmt.Println("slice 3:", l)

	// Também é possível declarar e inicializar um
	// slice em apenas uma linha.
	t := []string{"g", "h", "i"}
	fmt.Println("slice inicializada:", t)

	// Slices podem ser compsotas em estruturas
	// multi-dimensionais. O tamanho das slices internas
	// pode variar, diferente de arrays multi-dimensionais.
	twoD := make([][]int, 3)
	for i := 0; i < 3; i++ {
		innerLen := i + 1
		twoD[i] = make([]int, innerLen)
		for j := 0; j < innerLen; j++ {
			twoD[i][j] = i + j
		}
	}
	fmt.Println("bi-dimensional: ", twoD)
}
# Note que enquanto slices são tipos diferentes 
# de arrays, eles são exibidos de maneira similar
# pelo comando `fmt.Println`.
$ go run slices.go
vazio: [  ]
exibe slice: [a b c]
valor índice 2: c
len: 3
slice com acréscimo: [a b c d e f]
slice copiada: [a b c d e f]
slice 1: [c d e]
slice 2: [a b c d e]
slice 3: [c d e f]
slice inicializada: [g h i]
bi-dimensional:  [[0] [1 2] [2 3 4]]

# Veja esse [post](https://go.dev/blog/slices-intro)
# do time de Go para mais detalhes sobre o design e
# implementação de slices na linguagem.

# Agora que vimos arrays e slices, passaremos a estudar 
# outra estrutura de dados nativa de Go: maps.