如何将具有自定义 MarshalBSONValue 的结构的 nil 指针序列化为 BSON?
How to serialize nil pointer of structure with custom MarshalBSONValue into BSON?
mongodb我程序中使用的官方golang驱动
package main
import (
"fmt"
"github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
"log"
"strconv"
)
type Bar struct {
a int64
}
func (b Bar) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bsonx.String(fmt.Sprintf("%d", b.a)).MarshalBSONValue()
}
func (b *Bar) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
if t != bsontype.String {
return errors.Errorf("bsontype(%s) not allowed in Bar.UnmarshalBSONValue, only string accept", t.String())
}
str, _, ok := bsoncore.ReadString(data)
if !ok {
return errors.Errorf("decode string, but string not found")
}
dec, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return err
}
b = &Bar{a:dec}
return nil
}
type Foo struct {
Bar *Bar`bson:"Bar, omitempty"`
}
func main() {
f := Foo{}
_, err := bson.Marshal(f)
if err != nil {
log.Fatalf("Failed to marshal. Error: %v", err)
}
}
此程序将因错误而崩溃:
panic: value method main.Bar.MarshalBSONValue called using nil *Bar pointer
goroutine 1 [running]:
main.(*Bar).MarshalBSONValue(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
<autogenerated>:1 +0x87
reflect.Value.call(0x11ebc60, 0xc000010330, 0x293, 0x1218915, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/reflect/value.go:447 +0x461
您需要删除 omitempty 之前的 space:
type Foo struct {
Bar *Bar`bson:"Bar,omitempty"`
}
解析器无法处理", omitempty",因为代码如下:
for idx, str := range strings.Split(tag, ",") {
if idx == 0 && str != "" {
key = str
}
switch str {
case "omitempty":
mongodb我程序中使用的官方golang驱动
package main
import (
"fmt"
"github.com/pkg/errors"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
"log"
"strconv"
)
type Bar struct {
a int64
}
func (b Bar) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bsonx.String(fmt.Sprintf("%d", b.a)).MarshalBSONValue()
}
func (b *Bar) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
if t != bsontype.String {
return errors.Errorf("bsontype(%s) not allowed in Bar.UnmarshalBSONValue, only string accept", t.String())
}
str, _, ok := bsoncore.ReadString(data)
if !ok {
return errors.Errorf("decode string, but string not found")
}
dec, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return err
}
b = &Bar{a:dec}
return nil
}
type Foo struct {
Bar *Bar`bson:"Bar, omitempty"`
}
func main() {
f := Foo{}
_, err := bson.Marshal(f)
if err != nil {
log.Fatalf("Failed to marshal. Error: %v", err)
}
}
此程序将因错误而崩溃:
panic: value method main.Bar.MarshalBSONValue called using nil *Bar pointer
goroutine 1 [running]:
main.(*Bar).MarshalBSONValue(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
<autogenerated>:1 +0x87
reflect.Value.call(0x11ebc60, 0xc000010330, 0x293, 0x1218915, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/reflect/value.go:447 +0x461
您需要删除 omitempty 之前的 space:
type Foo struct {
Bar *Bar`bson:"Bar,omitempty"`
}
解析器无法处理", omitempty",因为代码如下:
for idx, str := range strings.Split(tag, ",") {
if idx == 0 && str != "" {
key = str
}
switch str {
case "omitempty":