Maison > développement back-end > Golang > Comment obtenir une copie approfondie des valeurs d'interface dans Go ?

Comment obtenir une copie approfondie des valeurs d'interface dans Go ?

Mary-Kate Olsen
Libérer: 2024-12-07 20:57:12
original
743 Les gens l'ont consulté

How to Achieve a Deep Copy of Interface Values in Go?

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)
}
Copier après la connexion

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
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal