我想在golang中使用mongodb并编写了一个示例应用程序:
package main
import (
"fmt"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"os"
)
type Session struct {
Id bson.ObjectId `bson:"_id"`
Data map[string]interface{} `bson:"data"`
}
func (rcv *Session) SetBSON(raw bson.Raw) error {
return raw.Unmarshal(rcv)
}
type Authen struct {
Name string `bson:"name"`
Email string `bson:"email"`
}
func main() {
uri := "mongodb://localhost/"
if uri == "" {
fmt.Println("no connection string provided")
os.Exit(1)
}
sess, err := mgo.Dial(uri)
if err != nil {
fmt.Printf("Can't connect to mongo, go error %v\n", err)
os.Exit(1)
}
defer sess.Close()
sess.SetSafe(&mgo.Safe{})
collection := sess.DB("test").C("sess")
a := &Authen{Name: "Cormier", Email: "cormier@example.com"}
s := &Session{}
s.Id = bson.NewObjectId()
s.Data = make(map[string]interface{})
s.Data["logged"] = a
err = collection.Insert(s)
if err != nil {
fmt.Printf("Can't insert document: %v\n", err)
os.Exit(1)
}
c := &Session{}
c.Id = bson.NewObjectId()
c.Data = make(map[string]interface{})
err = sess.DB("test").C("sess").Find(bson.M{}).One(c)
if err != nil {
fmt.Printf("got an error finding a doc %v\n")
os.Exit(1)
}
}
插入mongodb的工作就像一个魅力,但要解散参考我有以下恐慌:
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
runtime stack:
runtime.throw(0x6d84d9)
c:/go/src/runtime/panic.go:491 +0xad
runtime.newstack()
c:/go/src/runtime/stack.c:784 +0x5ef
runtime.morestack()
c:/go/src/runtime/asm_amd64.s:324 +0x86
我做错了什么?
答案 0 :(得分:4)
这个逻辑引入了无限递归:
func (rcv *Session) SetBSON(raw bson.Raw) error {
return raw.Unmarshal(rcv)
}
Session
实现了Setter接口,这意味着它的解组通过其SetBSON
方法发生,该方法是通过要求bson
包解组自己实现的,这将执行通过调用其SetBSON
方法。这永远不会结束,直到堆栈空间结束。
当然,解决方案是不要通过让Session
包再次解组它来实现bson
的自定义解组。