Maison >développement back-end >Golang >Go - Convertir le pointeur en tranche de structure en tranche d'interface

Go - Convertir le pointeur en tranche de structure en tranche d'interface

WBOY
WBOYavant
2024-02-09 14:57:081142parcourir

Go - 将指向结构切片的指针转换为接口切片

éditeur php Baicao Dans le langage de programmation Go, nous avons parfois besoin de convertir des pointeurs pour structurer des tranches en tranches d'interface. Cette conversion est très utile dans certaines situations spécifiques, comme lorsque nous devons modifier des éléments dans une tranche. En convertissant les pointeurs en tranches d'interface, nous pouvons facilement accéder et modifier les éléments de la tranche sans nous soucier des problèmes de cohérence et de synchronisation des données. Dans cet article, nous expliquerons comment effectuer cette conversion et fournirons quelques exemples d'applications pratiques.

Contenu de la question

J'ai découpé du code GoLang de production pour créer l'exemple suivant :

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var aData []AlphaStruct
    var bData []BetaStruct

    readData(&aData)
    readData(&bData)

    // Do other stuff with the loaded structures.
}

func readData(structSlicePointer any) {
    json.Unmarshal([]byte(
        "["+
            "{\"name\": \"John Smith\"},"+
            "{\"name\": \"Jane Doe\"}"+
            "]"),
        structSlicePointer)

    var initializers []Initializer

    // At this point I want to do:
    // initializers = structSlicePointer
    // However I can't find any type declarations or casts that will work with the rest of the code.

    for _, initializer := range initializers {
        initializer.Initialize()
    }
}

type Initializer interface {
    Initialize()
}

type AlphaStruct struct {
    Name string `json:"name"`
}

type BetaStruct struct {
    Name string `json:"name"`
}

func (es *AlphaStruct) Initialize() {
    fmt.Printf("In Alpha: %s\n", es.Name)
}

func (es *BetaStruct) Initialize() {
    fmt.Printf("In Beta: %s\n", es.Name)
}

J'ai beaucoup de structures et elles implémentent toutes la même interface.

L'idée est qu'après les avoir désérialisés (à partir de JSON), je souhaite appeler une méthode sur chaque objet chargé pour terminer l'initialisation de l'objet. Certains fichiers JSON ont des tableaux de niveau supérieur - c'est-à-dire qu'une fois désérialisés, ce sont des listes/tranches de structures.

Cependant, je ne trouve aucune combinaison d'énoncés qui me permettrait de faire simultanément ce qui suit :

  • Exécuter json.Unmarshal()
  • Parcourez chaque structure chargée et appelez les méthodes.

Évidemment, je peux diviser cela en deux fonctions (loadData et initializeData) pour exécuter les deux fonctions.

Existe-t-il un moyen de restructurer cela pour que cela fonctionne comme une méthode unique ?

Solution de contournement

Vous pouvez déclarer la méthode comme une méthode générique qui accepte une tranche de structure avec des membres qui implémentent l'interface Initializer.

Pour ce faire, vous pouvez déclarer votre méthode comme ceci :

func readData[T Initializer](structSlicePointer *[]T) {
    json.Unmarshal(
        []byte("[{\"name\": \"John Smith\"},{\"name\": \"Jane Doe\"}]"),
        structSlicePointer,
    )
    for _, initializer := range *structSlicePointer {
        initializer.Initialize()
    }
}

Notez que cela vous obligera à déclarer la valeur de la tranche en tant que pointeur à utiliser avec les méthodes de réception de pointeur sur une structure (par exemple []*AlphaStruct[]AlphaStruct) :

func main() {
    var aData []*AlphaStruct
    var bData []*BetaStruct

    readData(&aData)
    readData(&bData)
}

Sortie :

In Alpha: John Smith
In Alpha: Jane Doe
In Beta: John Smith
In Beta: Jane Doe

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer