Maison >développement back-end >Golang >Comment copier en profondeur les valeurs de l'interface dans Go ?

Comment copier en profondeur les valeurs de l'interface dans Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-26 14:56:11463parcourir

How to Deep Copy Interface Values in Go?

Comment copier en profondeur une valeur d'interface dans Go

Lorsque vous travaillez avec des interfaces dans Go, il est essentiel de réaliser que les interfaces contiennent une référence à leur valeur sous-jacente. La modification de la copie d'une valeur d'interface peut également affecter par inadvertance la valeur d'origine. Ce problème survient généralement lors de la création de valeurs d'interface à l'aide de pointeurs vers des types sous-jacents.

Comprendre le problème

Considérez l'interface utilisateur suivante :

type User interface {
    Name() string
    SetName(name string)
}

Et une implémentation avec une structure Admin :

type Admin struct {
    name string
}

func (a *Admin) Name() string {
    return a.name
}

func (a *Admin) SetName(name string) {
    a.name = name
}

Dans l'exemple fourni, un pointeur vers une structure Admin est affecté à la variable user1 de type User. Cependant, lorsque user2 est créé en lui attribuant la valeur user1, les deux variables font référence à la même structure Admin sous-jacente. Par conséquent, changer le nom via user2 change également le nom via user1.

Création de copies distinctes

Pour créer des copies distinctes des valeurs d'interface, il existe plusieurs options :

1. Utilisation de l'assertion de type et de la copie de structure

Cette méthode consiste à affirmer la valeur dans user1, à créer une copie de la structure sous-jacente et à envelopper l'adresse de la copie dans une nouvelle valeur utilisateur :

var user2 User
padmin := user1.(*Admin) // Obtain *Admin pointer
admin2 := *padmin        // Make a copy of the Admin struct
user2 = &admin2          // Wrap its address in another User
user2.SetName("user2")

2. Utilisation de Reflection

Reflection peut être utilisée pour créer une nouvelle valeur du même type dynamique que la valeur d'interface, garantissant une copie complète. Voici comment :

var user3 User
if reflect.TypeOf(user1).Kind() == reflect.Ptr {
    user3 = reflect.New(reflect.ValueOf(user1).Elem().Type()).Interface().(User)
} else {
    user3 = reflect.New(reflect.TypeOf(user1)).Elem().Interface().(User)
}
user3.SetName("user3")

En copiant profondément la valeur de l'interface, nous créons une copie distincte qui peut être modifiée sans affecter l'original.

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!

Déclaration:
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