msgpack库的神奇用法

 

一般来说,我们接收到消息,然后通过消息队列发送消息给worker的时候,会有些额外的字段,这些字段不属于实际的消息,我们想把实际的消息和发给worker的消息分开定义。这时候我们会把worker消息中一个字段定义为interface{}或者object,这个字段表示任意的实际消息。

 

type WorkerMsg struct {
      ID  int
      Route string
      Msg interface{} // 实际消息
}

一切看起来很完美,但是问题来了,当我们用msgpack库decode消息到worker消息结构体的时候,这个Msg字段变成了一堆object的集合体,这时候,我们不得不再写一个函数把这些object,一个一个地复制到实际消息的结构体上,而这个函数是极其复杂的,很容易写错,而且性能也不好。

那么,我们还有更好的办法吗?其实我们可以这样写:

 

package main

import (
    "bytes"
    "fmt"

    "github.com/vmihailenco/msgpack"
)

type Abc struct {
    BB   int
    Haha int
}

type Msg struct {
    ID  int
    Msg interface{}
}

func main() {

    var msg Msg
    msg.Msg = Abc{BB: 2, Haha: 3}
    var buf bytes.Buffer
    msgpack.NewEncoder(&buf).StructAsArray(true).Encode(msg)
    data := buf.Bytes()
    
    var workerMsg Msg
    realMsg := &Abc{}
    workerMsg.Msg = realMsg
    msgpack.Unmarshal(data, &workerMsg)
    fmt.Println(workerMsg, realMsg)

}

 

可看到msgpack将数据解到msgD上,因为用的是指针,同时也解到了realMsg结构上!  这意味着我们不再需要重新定义一个新的结构体,而是组合这些结构体来实现我们的功能。

 

posted on 2017-11-30 16:05  dearplain  阅读(9581)  评论(0编辑  收藏  举报