Go Faire des copies de structure


Exemple

Une structure peut simplement être copiée en utilisant l'affectation.

type T struct {
    I int
    S string
}

// initialize a struct
t := T{1, "one"}

// make struct copy
u := t // u has its field values equal to t

if u == t { // true
    fmt.Println("u and t are equal") // Prints: "u and t are equal"
}

Dans le cas ci-dessus, 't' et «u» sont maintenant des objets séparés (valeurs de structure).

Comme T ne contient aucun type de référence (tranches, carte, canaux), ses champs, t et u ci-dessus peuvent être modifiés sans se toucher.

fmt.Printf("t.I = %d, u.I = %d\n", t.I, u.I) // t.I = 100, u.I = 1

Cependant, si T contient un type de référence, par exemple:

type T struct {
    I  int
    S  string
    xs []int // a slice is a reference type
}

Ensuite, une simple copie par affectation copiera également la valeur du champ de type de tranche dans le nouvel objet. Cela se traduirait par deux objets différents faisant référence au même objet de tranche.

// initialize a struct
t := T{I: 1, S: "one", xs: []int{1, 2, 3}}

// make struct copy
u := t // u has its field values equal to t

Étant donné que les deux u et t se réfèrent à la même tranche dans leur champ, xs mettant à jour une valeur dans la tranche d'un objet reflète le changement dans l'autre.

// update a slice field in u
u.xs[1] = 500

fmt.Printf("t.xs = %d, u.xs = %d\n", t.xs, u.xs)
// t.xs = [1 500 3], u.xs = [1 500 3]

Par conséquent, des précautions supplémentaires doivent être prises pour s'assurer que cette propriété de type référence ne produit pas de comportement involontaire.

Pour copier des objets ci-dessus par exemple, une copie explicite du champ de la tranche peut être effectuée:

// explicitly initialize u's slice field
u.xs = make([]int, len(t.xs))
// copy the slice values over from t
copy(u.xs, t.xs)

// updating slice value in u will not affect t
u.xs[1] = 500

fmt.Printf("t.xs = %d, u.xs = %d\n", t.xs, u.xs)
// t.xs = [1 2 3], u.xs = [1 500 3]