Da trilha de Go Este conceito ainda não saiu como card do dia. ir para o card de hoje

Go Coleções Básico

Slices

Slices são a estrutura de dados mais usada em Go para representar sequências de tamanho variável. Diferente de arrays, que têm tamanho fixo, um slice é uma visão sobre um array subjacente (o backing array), composta por um ponteiro para o primeiro elemento visível, um len (quantos elementos o slice enxerga) e um cap (quantos elementos cabem desde esse ponto até o fim do array subjacente).

Você cria slices com literais como []int{1, 2, 3} ou com make([]int, len, cap). A função append adiciona elementos e devolve um novo slice; se houver capacidade sobrando, ela reaproveita o mesmo array, senão aloca um maior e copia os dados.

A operação de fatiar (s[a:b]) cria um novo slice que compartilha o mesmo backing array. Isso é eficiente, mas perigoso: alterar um elemento de um slice pode refletir no outro. Entender len, cap e esse compartilhamento evita bugs sutis de aliasing.

Pontos-chave

  • len(s) é o número de elementos visíveis; cap(s) é o espaço disponível até o fim do array subjacente.
  • append pode reaproveitar o array (se cap sobra) ou realocar um novo (quando estoura a capacidade).
  • Fatiar (s[i:j]) cria um novo slice que compartilha o mesmo backing array do original.
  • Alterações em elementos compartilhados aparecem nos dois slices; isso é aliasing.
  • Use copy ou slices.Clone quando precisar de um slice independente.
slices.go
package main

import "fmt"

func main() {
	// Slice com len 3 e cap 3
	s := []int{10, 20, 30}
	fmt.Println("s =", s, "len =", len(s), "cap =", cap(s))

	// append pode crescer reaproveitando ou realocando o backing array
	s = append(s, 40)
	fmt.Println("após append:", s, "len =", len(s), "cap =", cap(s))

	// Fatiar: novo slice compartilha o mesmo backing array
	a := s[1:3]
	fmt.Println("a =", a, "len =", len(a), "cap =", cap(a))

	// Alterar a[0] reflete em s[1], pois compartilham memória
	a[0] = 99
	fmt.Println("s =", s, "a =", a)

	// append em 'a' sobrescreve s[3] porque há capacidade sobrando
	a = append(a, 77)
	fmt.Println("s =", s, "a =", a)
}

Exercícios

  1. 1
    Fácil

    Inspecionando len e cap

    Crie um slice com make([]string, 2, 5), atribua "a" e "b" nas posições 0 e 1 e imprima o len e o cap. Depois faça append de "c" e imprima novamente len e cap.

    Resolver
  2. 2
    Médio

    Fatiando e observando o aliasing

    Dado nums := []int{1, 2, 3, 4, 5}, crie um sub-slice sub := nums[1:4] e imprima nums, sub e o cap(sub). Depois altere sub[0] = 99 e imprima nums novamente para mostrar o compartilhamento.

    Resolver
  3. 3
    Desafio

    append sobrescrevendo o backing array compartilhado

    Escreva uma função addAndReport(base []int) ([]int, []int) que recebe um slice, cria tail := base[1:] e faz tail = append(tail, 100). Retorne base e tail. No main, chame com []int{1, 2, 3} e mostre que o append sobrescreveu uma posição de base.

    Resolver

Continue estudando