英文:
Issues retrieving MongoDB documents with Go
问题
我有以下的代码,但我不确定为什么它没有返回一个Notes的切片。我正在使用来自labix.org的mgo库连接到MongoDB,并遵循他们的在线文档。
type Note struct {
Url string
Title string
Date string
Body string
}
func loadNotes() ([]Note) {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
// 可选。将会话切换到单调行为。
session.SetMode(mgo.Monotonic, true)
c := session.DB("test").C("notes")
notes := []Note{}
iter := c.Find(nil).Limit(100).Iter()
err = iter.All(¬es)
if err != nil {
panic(iter.Err())
}
return notes
}
func main() {
notes := loadNotes()
for note := range notes {
fmt.Println(note.Title)
}
}
如果我只打印出notes
,我得到的是看起来像是两个结构体的切片,但我无法通过notes.Title
或其他方式访问它们。
[{ Some example title 20 September 2012 Some example content}]
这是我的文档的样子:
> db.notes.find()
{ "_id" : "some-example-title", "title" : "Some example title", "date" : "20 September 2012", "body" : "Some example content" }
真正的问题是它将notes作为一个大的切片返回,而不是一个Note{}
(我想是这样的?)
如果我做了明显错误的事情,请提供任何见解。
英文:
I have the following code, and I'm not sure why it is not returning a slice of Notes. I am using the mgo library from labix.org to connect to MongoDB and following their online documentation.
type Note struct {
Url string
Title string
Date string
Body string
}
func loadNotes() ([]Note) {
session, err := mgo.Dial("localhost")
if err != nil {
panic(err)
}
defer session.Close()
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
c := session.DB("test").C("notes")
notes := []Note{}
iter := c.Find(nil).Limit(100).Iter()
err = iter.All(&notes)
if err != nil {
panic(iter.Err())
}
return notes
}
func main() {
notes := loadNotes()
for note := range notes {
fmt.Println(note.Title)
}
}
If I just print out notes
I get what looks like a slice of two structs, but I can't access them by means of notes.Title
or anything like that.
[{ Some example title 20 September 2012 Some example content}]
This is what my documents look like:
> db.notes.find()
{ "_id" : "some-example-title", "title" : "Some example title", "date" : "20 September 2012", "body" : "Some example content" }
The real issue is that it's returning the notes as one big slice rather than a Note{}
(I think?)
If I'm doing something obviously wrong, any insight would help.
答案1
得分: 5
你的问题在这里:
for note := range notes {
fmt.Println(note.Title)
}
应该改为:
for _, note := range notes {
fmt.Println(note.Title)
}
在切片上使用range语句会返回形式为i, v
的一对值,其中i是切片中的索引,v是该索引处的项。由于你省略了第二个值,所以你在循环中使用的是索引,而不是Note
值。
这在规范的RangeClause部分有说明:http://golang.org/ref/spec#RangeClause
英文:
your problem is here:
for note := range notes {
fmt.Println(note.Title)
}
it should read:
for _, note := range notes {
fmt.Println(note.Title)
}
using a range statement on a slice returns pairs of the form i, v
, where i is the index in the slice, and v is the item at the index in that slice. Since you omitted the second value, you're looping on indexes, not on Note
values.
It's in the RangeClause section of the spec: http://golang.org/ref/spec#RangeClause
答案2
得分: 2
看起来对我来说它正在工作。notes是一个你指示的结构体切片。
for _, n := range notes {
n.Title // 对标题进行操作
n.Url // 对URL进行操作
}
或者,如果你只想要第一个:
notes[0].Title
也可以工作。
结构体切片不能像结构体本身那样进行索引,因为它不是一个结构体。
英文:
It looks like it's working to me. notes is a slice of structs as you indicated.
for _, n := range notes {
n.Title // do something with title
n.Url // do something with url
}
or alternatively if you just want the first one:
notes[0].Title
should work as well.
A slice of structs can't be indexed as if it were a struct itself because it isn't a struct.
答案3
得分: 0
iter.All()一次性将整个结果集检索到一个切片中。如果你只想要一行数据,使用iter.Next()。请参阅https://groups.google.com/forum/#!msg/mgo-users/yUGZi70ik9Y/J8ktshJgF7QJ
英文:
iter.All() retrieves the whole result set at once into a slice. If you just want one row, use iter.Next(). See https://groups.google.com/forum/#!msg/mgo-users/yUGZi70ik9Y/J8ktshJgF7QJ
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论