Heim > Backend-Entwicklung > Golang > Wie kann ich Daten in Go effektiv in Schnittstellentypen entmarshalieren?

Wie kann ich Daten in Go effektiv in Schnittstellentypen entmarshalieren?

Susan Sarandon
Freigeben: 2024-12-21 14:35:10
Original
284 Leute haben es durchsucht

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

Unmarshaling zu Schnittstellentyp

In Go umfasst das Marshalling und Unmarshaling von Daten die Konvertierung zwischen speicherinternen Darstellungen und einem serialisierten Format. Während es einfach ist, Daten von Schnittstellentypen zu marshalieren, kann das Unmarshaling für Schnittstellentypen eine Herausforderung darstellen.

Erklärung

Unmarshaling beinhaltet das Erstellen einer konkreten Instanz eines Typs, um die zu empfangen Daten. Beim Unmarshaling auf einen Schnittstellentyp kann der Unmarshaller jedoch den spezifischen Typ des konkreten zu instanziierenden Objekts nicht bestimmen.

Lösung

Um dieses Problem zu lösen, gibt es einen Ansatz um die Unmarshaler-Schnittstelle für benutzerdefinierte Typen zu implementieren. Durch die Implementierung von Unmarshaler bieten Sie dem Unmarshaller eine benutzerdefinierte Möglichkeit, eine Instanz des konkreten Typs zu erstellen und seine Felder zu füllen.

type MyType struct {
    // ... fields
}

func (m *MyType) Unmarshal(data []byte) error {
    // Unmarshal the data into the fields of MyType
    return nil
}
Nach dem Login kopieren

Diese benutzerdefinierte Unmarshaling-Methode kann dann verwendet werden, um JSON-Daten in Instanzen von MyType zu entmarshalieren .

Alternativ können Sie Ihren Typ mit „typeinfo“ annotieren, um den genauen Typ anzugeben, der aufgehoben werden soll zu.

{"Type": "YourTypeName", ...}
Nach dem Login kopieren

Beispiel

Betrachten Sie den folgenden geänderten Code:

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)
}
Nach dem Login kopieren

Wenn Sie diesen geänderten Code ausführen, werden Sie sehen Erfolgreiches Unmarshaling von Schnittstellentypen über eine RPC-Verbindung.

Das obige ist der detaillierte Inhalt vonWie kann ich Daten in Go effektiv in Schnittstellentypen entmarshalieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage