亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

解組到接口類型

解組到接口類型

Go
幕布斯6054654 2021-11-08 10:18:31
我有一些代碼被丟棄了,實際上我很難過 - 我以前使用過 RPC 和 JSON 方面的東西,但是當它在本地工作正常時,我似乎無法讓它在 RPC 上工作。package mainimport (    "log"    "net"    "net/rpc"    "net/rpc/jsonrpc"    "reflect")type Foo interface {    SayHello() error}type fakeFoo struct {    internalValue string}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 {    log.Println("availableFoos:", reflect.TypeOf(mm.availableFoos))    log.Println("*out is", reflect.TypeOf(*out))    *out = append(in, mm.availableFoos...)    log.Println("Out is:", reflect.TypeOf(*out))    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)    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)    }(也在這里,但沒有可用的 tcp urgh!http: //play.golang.org/p/HmK-K09D2J )輸出非常令人驚訝,因為它表明編組出了問題而不是實際數據 - 在wireshark中運行它我可以看到以正確的形式發送的數據(我在另一個問題中使用類似的技術取得了成功)但是可以不是為了我的生活得到這個停止拋出編組錯誤。我是否缺少接口/類型技巧,或者這是 Go 編組中的錯誤?
查看完整描述

1 回答

?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

所有編組/解組都有這個問題。


您可以從接口類型變量進行編組,因為對象存在于本地,因此反射器知道底層類型。


您不能解組到接口類型,因為反射器不知道將哪種具體類型提供給新實例以接收編組數據。


在一些編組/解組框架中,我們需要額外的信息來幫助反射器。比如在Java Json( jackson )中,我們使用JsonTypeInfo注解來指定類的類型,參考這個。


對于 golang,你可以自己為自己的類型實現Unmarshaler接口。請參閱如何解組 JSON?


// RawString is a raw encoded JSON object.

// It implements Marshaler and Unmarshaler and can

// be used to delay JSON decoding or precompute a JSON encoding.

type RawString string


// MarshalJSON returns *m as the JSON encoding of m.

func (m *RawString) MarshalJSON() ([]byte, error) {

    return []byte(*m), nil

}


// UnmarshalJSON sets *m to a copy of data.

func (m *RawString) UnmarshalJSON(data []byte) error {

    if m == nil {

        return errors.New("RawString: UnmarshalJSON on nil pointer")

    }

    *m += RawString(data)

    return nil

}


const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}`


type A struct {

    I int64

    S RawString `sql:"type:json"`

}


func main() {

    a := A{}

    err := json.Unmarshal([]byte(data), &a)

    if err != nil {

        log.Fatal("Unmarshal failed", err)

    }

    fmt.Println("Done", a)

}


查看完整回答
反對 回復 2021-11-08
  • 1 回答
  • 0 關注
  • 192 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號