【轉】msgpack庫的神奇用法
阿新 • • 發佈:2019-02-16
一般來說,我們接收到訊息,然後通過訊息佇列傳送訊息給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結構上! 這意味著我們不再需要重新定義一個新的結構體,而是組合這些結構體來實現我們的功能。