解組到介面類型
在 Go 中,編組和解組資料涉及記憶體表示和序列化格式之間的轉換。雖然從介面類型編組資料很簡單,但解組到介面類型可能會帶來挑戰。
說明
解組涉及建立類型的特定實例以接收資料。但是,當解組到介面類型時,解組器無法確定要實例化的特定物件的特定類型。
解決方案
要解決此問題,一種方法是實作自訂類型的 Unmarshaler 介面。透過實作 Unmarshaler,您可以為解組器提供一種自訂方法來建立特定類型的實例並填入其欄位。
type MyType struct { // ... fields } func (m *MyType) Unmarshal(data []byte) error { // Unmarshal the data into the fields of MyType return nil }
然後可以使用此自訂解組方法將 JSON 資料解組到 MyType 實例中.
或者,您可以使用 typeinfo註解您的類型,以指定要解組的確切類型
{"Type": "YourTypeName", ...}
範例
考慮以下修改後的程式碼:
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) }
考慮以下修改後的程式碼:
考慮以下修改後的程式碼:考慮以下修改後的程式碼:當您執行此修改後的程式碼時,您將看到透過RPC 連線成功解組介面類型。以上是如何有效地將資料解組到 Go 中的介面類型?的詳細內容。更多資訊請關注PHP中文網其他相關文章!