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:
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:
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:
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:
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