slices.Clone în Go

Returnează o copie a unui slice, cu memorie proprie: modificările copiei nu afectează originalul.

Sintaxă
import "slices"

func Clone[S ~[]E, E any](s S) S

Ce face slices.Clone

Când atribui un slice altei variabile (b := a), ambele folosesc aceeași memorie: o schimbare în b se vede și în a. slices.Clone(s) creează o copie cu memoria ei, deci cele două devin independente.

Copia este superficială: elementele sunt copiate prin atribuire. Dacă elementele sunt pointeri, map-uri sau alte slice-uri, copia și originalul vor indica tot spre aceleași date. Un slice nil rămâne nil.

Înainte de Go 1.21 se scria append([]T(nil), s...) sau make + copy.

Parametri

Parametru Descriere
s Slice-ul copiat.

Ce returnează

Un slice nou cu aceleași elemente.

Exemple

Exemplul 1: Atribuire față de clonare

package main

import (
    "fmt"
    "slices"
)

func main() {
    note := []int{7, 8, 9}
    alias := note
    copie := slices.Clone(note)

    alias[0] = 10
    copie[1] = 5
    fmt.Println("note:", note)
    fmt.Println("alias:", alias)
    fmt.Println("copie:", copie)
}

Rezultat

note: [10 8 9]
alias: [10 8 9]
copie: [7 5 9]

Exemplul 2: Copia este superficială

Elementele sunt slice-uri, deci copia exterioară împarte rândurile interioare cu originalul.

package main

import (
    "fmt"
    "slices"
)

func main() {
    tabel := [][]int{{1, 2}, {3, 4}}
    copie := slices.Clone(tabel)
    copie[0][0] = 99         // modifică un rând comun
    copie[1] = []int{0, 0}   // înlocuiește doar în copie
    fmt.Println(tabel)
    fmt.Println(copie)
    fmt.Println(slices.Clone([]int(nil)) == nil)
}

Rezultat

[[99 2] [3 4]]
[[99 2] [0 0]]
true

Greșeli frecvente

  • Crezi că b := a copiază datele: copiază doar „antetul” slice-ului, memoria rămâne comună.
  • Te aștepți ca Clone să copieze și datele din interiorul elementelor (copie profundă): pentru asta scrii tu o buclă.

Comenzi înrudite

  • slices.Concat: Lipește mai multe slice-uri într-unul nou, alocat o singură dată.
  • maps.Clone: Clone face o copie a unui map; Copy copiază toate perechile din src în dst, suprascriind cheile existente.
  • slices.Grow: Grow rezervă loc pentru încă n elemente fără realocări ulterioare; Clip elimină capacitatea nefolosită.