package code_test
import (
"encoding/json"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"testing"
)
type Data struct {
Type int32 `bson:"Type"`
IValue IGetter `bson:"IValue"`
}
func (m *Data) UnmarshalBSON(b []byte) error {
tempData := &struct {
Type int32 `bson:"Type"`
}{}
err := bson.Unmarshal(b, tempData)
if err != nil {
fmt.Println("A", err)
}
switch tempData.Type {
case 100:
reallyData := &struct {
Type int32 `bson:"Type"`
IValue *AGetter `bson:"IValue"`
}{}
err = bson.Unmarshal(b, reallyData)
m.Type = reallyData.Type
m.IValue = reallyData.IValue
}
return nil
}
type IGetter interface {
Get() string
MarshalBSON() ([]byte, error)
}
type AGetter struct {
DataA string
}
func (m *AGetter) Get() string {
return "AGetter" + m.DataA
}
func (m *AGetter) MarshalBSON() ([]byte, error) {
t := &struct {
DataA string
}{
DataA: m.DataA,
}
return bson.Marshal(t)
//return bson.Marshal(m)
}
func TestD(t *testing.T) {
{
data := &Data{
Type: 100,
IValue: &AGetter{
DataA: "aaa",
},
}
byteData, err := bson.Marshal(data)
if err != nil {
fmt.Println(err)
}
var after = &Data{}
err = bson.Unmarshal(byteData, after)
fmt.Printf("%s\n", Stringify(after))
}
}
func Stringify(o interface{}) string {
//data, err := json.MarshalIndent(o, "", " ")
data, err := json.Marshal(o)
if err != nil {
//xlog.Error(err)
return err.Error()
}
return string(data)
}
此代码工作成功。
但我不想写 MarshalBSON 函数。
就像在mgo驱动程序中一样:如何在mgo(Go)中使用接口类型作为模型?
似乎只有 UnmarshalBSON 功能是必要的。
但是当我在 mongo-go-driver 中删除 MarshalBSON 时,出现错误“找不到 code_test.IGetter 的编码器”
在找到一个好的解决方案之前,我使用这段代码来解决问题......
package mongo_test_test
import (
"fmt"
mgoBson "github.com/globalsign/mgo/bson"
"go.mongodb.org/mongo-driver/bson"
"testing"
"xkit"
)
type Data struct {
Type int32 `bson:"Type"`
IValue IGetter `bson:"IValue"`
}
func (m *Data) UnmarshalBSON(b []byte) error {
tempData := &struct {
Type int32 `bson:"Type"`
}{}
err := bson.Unmarshal(b, tempData)
if err != nil {
fmt.Println("A", err)
}
switch tempData.Type {
case 100:
reallyData := &struct {
Type int32 `bson:"Type"`
IValue *AGetter `bson:"IValue"`
}{}
err = bson.Unmarshal(b, reallyData)
m.Type = reallyData.Type
m.IValue = reallyData.IValue
}
return nil
}
func (m *Data) MarshalBSON() ([]byte, error) {
return mgoBson.Marshal(m)
}
type IGetter interface {
Get() string
}
type AGetter struct {
DataA string
}
func (m *AGetter) Get() string {
return "AGetter" + m.DataA
}
func TestD(t *testing.T) {
{
data := &Data{
Type: 100,
IValue: &AGetter{
DataA: "aaa",
},
}
byteData, err := bson.Marshal(data)
if err != nil {
fmt.Println(err)
}
var after = &Data{}
err = bson.Unmarshal(byteData, after)
fmt.Printf("%s\n", xkit.Stringify(after))
}
}