Copie approfondie des valeurs d'interface dans Go
La copie d'une valeur d'interface directement dans Go entraîne une copie superficielle, ce qui signifie que les modifications apportées à la valeur copiée La valeur affecte également l'original. En effet, les interfaces contiennent une référence au type concret sous-jacent.
Cause du changement de nom
Pour comprendre le problème dans le code fourni, analysons le fonctionnement des valeurs d'interface. . L'interface utilisateur représente un contrat, et l'administrateur et l'utilisateur mettent en œuvre ce contrat. Lors de l'attribution de user1 à user2, nous créons essentiellement une référence à la même instance d'administration. La modification de la méthode Name() de l'utilisateur 2 modifie directement l'instance d'administration partagée, ce qui modifie par conséquent également le nom de l'utilisateur 1.
Solution avec réflexion
Pour obtenir une copie complète, nous avons besoin pour créer une nouvelle instance du type concret sous-jacent et l'envelopper dans une nouvelle valeur d'interface utilisateur. Une façon d’y parvenir est d’utiliser la réflexion. Nous pouvons utiliser les fonctions réflexion.ValueOf() et réflexion.Elem() pour obtenir la valeur sous-jacente stockée dans user1. Ensuite, nous pouvons utiliser Reflect.New() pour créer une nouvelle instance du même type et Reflect.MethodByName() pour obtenir la méthode Name(). Enfin, nous pouvons appeler la méthode SetName() sur la nouvelle instance et l'envelopper dans une nouvelle valeur d'interface utilisateur.
func CloneUser(user User) User { val := reflect.ValueOf(user) if val.Kind() != reflect.Ptr { panic("expected pointer") } elem := val.Elem() t := elem.Type() newElem := reflect.New(t).Elem() newElem.MethodByName("SetName").Call([]reflect.Value{reflect.ValueOf(newElem.String())}) return newElem.Interface().(User) }
En utilisant cette fonction, nous pouvons créer une copie qui n'affecte pas l'original :
var user2 User = CloneUser(user1) user2.SetName("user2") fmt.Println(user1.Name(), user2.Name()) // Outputs: user1 user2
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!