看代碼
可以看出 protobuf,可以解決這個(gè)問題锁施。
解決方案是
any.Any
, 包含一個(gè) TypeUrl,
生成的 message 會(huì)注冊(cè) TypeUrl 到全局
反序列化的時(shí)候处铛,依據(jù) TypeUrl 做選擇
實(shí)際 json 也可以依據(jù)這個(gè)思路
package main
import (
"encoding/json"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/wrappers"
)
type User struct {
Name string
Value interface{}
}
//go:generate protoc -I . --go_out=plugins=grpc:. user.proto
func main() {
demo1()
}
func demo1() {
u := &User{
Name: "int32",
Value: &wrappers.Int32Value{Value: 13},
}
bs, err := json.Marshal(u)
if err != nil {
panic(err)
}
var u2 *User
if err := json.Unmarshal(bs, &u2); err != nil {
panic(err)
}
fmt.Printf("%v %T\n", u2, u2.Value)
}
func demo2() {
value := wrappers.Int32Value{Value: 13}
any, err := ptypes.MarshalAny(&value)
if err != nil {
panic(err)
}
u := &User2{
Name: "int32",
Value: any,
}
bs, err := proto.Marshal(u)
if err != nil {
panic(err)
}
fmt.Printf("%q\n", string(bs))
var u2 = &User2{}
if err := proto.Unmarshal(bs, u2); err != nil {
panic(err)
}
fmt.Printf("%#v %T\n", u2, u2.Value)
detail := &ptypes.DynamicAny{}
if err := ptypes.UnmarshalAny(u2.Value, detail); err != nil {
panic(err)
}
v := detail.Message.(*wrappers.Int32Value)
fmt.Printf("%v %T\n", v, v)
}
syntax = "proto3";
import "google/protobuf/any.proto";
// option go_package = "google.golang.org/genproto/googleapis/rpc/status;status";
package main;
message User2 {
string name = 1;
google.protobuf.Any value = 2;
}