Maison > développement back-end > Golang > Comment puis-je regrouper efficacement les données vers les types d'interface dans Go ?

Comment puis-je regrouper efficacement les données vers les types d'interface dans Go ?

Susan Sarandon
Libérer: 2024-12-21 14:35:10
original
283 Les gens l'ont consulté

How Can I Effectively Unmarshal Data to Interface Types in Go?

Unmarshal to Interface Type

Dans Go, le marshaling et le démarshaling des données impliquent une conversion entre des représentations en mémoire et un format sérialisé. Bien qu'il soit simple de rassembler les données des types d'interface, le démarshalage vers les types d'interface peut poser un défi.

Explication

Le démarshalage implique la création d'une instance concrète d'un type pour recevoir le données. Cependant, lors du démarshalage sur un type d'interface, le démarshaller ne peut pas déterminer le type spécifique de l'objet concret à instancier.

Solution

Pour résoudre ce problème, une approche consiste pour implémenter l'interface Unmarshaler pour les types personnalisés. En implémentant Unmarshaler, vous fournissez au unmarshaller un moyen personnalisé de créer une instance du type concret et de remplir ses champs.

type MyType struct {
    // ... fields
}

func (m *MyType) Unmarshal(data []byte) error {
    // Unmarshal the data into the fields of MyType
    return nil
}
Copier après la connexion

Cette méthode de démarshaling personnalisée peut ensuite être utilisée pour démarshaler les données JSON en instances de MyType. .

Vous pouvez également annoter votre type avec typeinfo pour spécifier le type exact à annuler. à.

{"Type": "YourTypeName", ...}
Copier après la connexion

Exemple

Considérez le code modifié suivant :

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net"
    "net/rpc"
    "net/rpc/jsonrpc"
    "reflect"
    "time"
)

type Foo interface {
    SayHello() error
}

type fakeFoo struct {
    internalValue string
}

// Implement Unmarshaler interface for fakeFoo
func (f *fakeFoo) Unmarshal(data []byte) error {
    log.Println("Unmarshaling fakeFoo...")
    type tmpType fakeFoo
    return json.Unmarshal(data, (*tmpType)(f))
}

func NewFakeFoo() *fakeFoo {
    f := &fakeFoo{}
    f.internalValue = "123456789012347"
    return f
}

func (m *fakeFoo) SayHello() error {
    return nil
}

type FooManager struct {
    availableFoos []Foo
}

func NewFooManager() *FooManager {
    p := new(FooManager)
    p.availableFoos = make([]Foo, 0)
    return p
}

func AddFoo(mm *FooManager, m Foo) {
    mm.availableFoos = append(mm.availableFoos, m)
    log.Println("Added type ", reflect.TypeOf(m))
}

func (mm *FooManager) GetAvailableFoos(in []Foo, out *[]Foo) error {

    *out = append(in, mm.availableFoos...)

    return nil
}

func startServer(mm *FooManager) {
    server := rpc.NewServer()
    server.Register(mm)

    l, e := net.Listen("tcp", ":8222")
    if e != nil {
        log.Fatal("listen error:", e)
    }

    for {
        conn, err := l.Accept()
        log.Println("Incoming!")
        if err != nil {
            log.Fatal(err)
        }

        go server.ServeCodec(jsonrpc.NewServerCodec(conn))
    }
}

func main() {
    fake1 := NewFakeFoo()

    fooHolder := NewFooManager()
    AddFoo(fooHolder, fake1)
    go startServer(fooHolder)

    time.Sleep(1 * time.Second) // Sleep to allow server to start

    log.Println("Using standard function call")
    var foos []Foo
    fooHolder.GetAvailableFoos(foos, &foos)
    log.Println(foos)

    log.Println("Using RPC call")
    conn, err := net.Dial("tcp", "localhost:8222")
    if err != nil {
        log.Fatalln(err)
    }
    defer conn.Close()
    c := jsonrpc.NewClient(conn)

    err = c.Call("FooManager.GetAvailableFoos", foos, &foos)
    if err != nil {
        log.Fatal("GetAvailableFoos error:", err)
    }
    log.Println("Success: ", foos)
}
Copier après la connexion

Lorsque vous exécutez ce code modifié, vous verrez démarshaling réussi des types d'interface sur une connexion RPC.

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