Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top