Rafael

Engenheiro de Software

Olá, Eu sou Rafael. Estou construindo coisas para a web e mobile.

Um desenvolvedor dedicado a criar experiências digitais de alto desempenho, acessíveis e limpas. Eu me especializo em transformar problemas complexos em soluções de engenharia elegantes.

Desvendando o SLICE em GO

Antes de tudo minha versão do GO: go1.25.6

O Slice em GO é por baixo dos panos uma array ele tem um ponteiro um tamanho e uma capacidade.

O tamanho para saber aonde ir, capacidade para saber o quanto ele consegue receber. Slicing refere-se à operação de criar um novo slice a partir de um array ou slice existente usando a sintaxe de intervalo semiaberto a[low:high].

Vamos a um exemplo para entender melhor:

GO
package main

import "fmt"

func main() {

	slice := []int{10, 20, 30, 50, 60, 70, 80, 90, 100}
	fmt.Printf("Quatro primeiros elementos: %v\n", slice[:4])
	fmt.Printf("Exibir elementosa partir do quinto elemento: %v\n", slice[4:])
	fmt.Printf("Exibir do terceiro ao sexto elemento: %v\n", slice[2:6])
	fmt.Printf("Exibir todos os elementos: %v\n", slice[:])

}

Entendendo a capacidade e tamanho dos elementos:

GO
package main

import "fmt"

func main() {

	slice := []int{10, 20, 30, 50, 60, 70, 80, 90, 100}

	// Traz todo o slice. O comprimento é 9 e a capacidade é 9.
	fmt.Printf("len=%d cap=%d %v\n", len(slice), cap(slice), slice)

	// Vai até o indice 4. O tamanho é 4 e a capacidade é 9.
	fmt.Printf("len=%d cap=%d %v\n", len(slice[:4]), cap(slice[:4]), slice[:4])

	// Ignora os dois primeiros elementos. O tamanho é 7 e a capacidade é 7.
	// A capacidade é 7 porque ignorou o começo do slice.
	fmt.Printf("len=%d cap=%d %v\n", len(slice[2:]), cap(slice[2:]), slice[2:])

	// Ignora os dois primeiros elementos e vai até o indice 5. O tamanho é 3 e a capacidade é 7.
	// A capacidade é 7 porque ignorou o começo do slice.
	fmt.Printf("len=%d cap=%d %v\n", len(slice[2:5]), cap(slice[2:5]), slice[2:5])

}

Para aumentar a capacidade do Slice você pode dar um append mas ele dá uma capacidade dobrada pelo tamanho da capacidade:

GO
package main

import "fmt"

func main() {

	slice := []int{10, 20, 30, 50, 60, 70, 80, 90, 100}
	slice = append(slice, 110)

	// Traz todo o slice. O comprimento é 10 e a capacidade é 18.
	// Ele dobrou a capacidade porque o slice original tinha capacidade 9.
	fmt.Printf("len=%d cap=%d %v\n", len(slice), cap(slice), slice)
}

Isso é o crescimento automático da capacidade do slice ao fazer append.Quando a capacidade atual é excedida, o runtime realoca o array subjacente com uma capacidade maior (geralmente dobrando). Isso pode ser custoso em algumas situações seria bom utilizar um tamanho fixo.

Vamos ver agora com dois append:

GO
package main

import "fmt"

func main() {

	slice := []int{10, 20, 30, 50, 60, 70, 80, 90, 100}
	slice = append(slice, 110)

	// Traz todo o slice. O comprimento é 10 e a capacidade é 18.
	// Ele dobrou a capacidade porque o slice original tinha capacidade 9.
	fmt.Printf("len=%d cap=%d %v\n", len(slice), cap(slice), slice)

	slice = append(slice, 120)
	// Traz todo o slice. O comprimento é 11 e a capacidade é 18.
	// Ele não dobrou a capacidade porque o slice já tinha capacidade suficiente para acomodar o novo elemento.
	fmt.Printf("len=%d cap=%d %v\n", len(slice), cap(slice), slice)

}

Pode notar que a capacidade no segundo append não foi dobrada pois não excedeu a capacidade atual de 18.

0 comentários

Deixe seu comentário