1

I have following (untested) function:

func Execute(task MyInterface) {
    db := session.DB(task.Database()).C(task.Collection())
    var tasks []MyInterface
    db.Find(nil).All(&tasks)
    for _, t := range tasks { t.Do() }
}

I want to give my function a struct that implements interface MyInterface. It should then retrieve some values from mongodb and call a method on the retrieved structs.

Problem is error: reflect.Set: value of type bson.M is not assignable to type mypkg.MyInterface - is there some way to make this work? I tried to instantiate tasks using the type of the original struct, but couldn't get it working.

Any help would be appreciated - thanks :)

2
  • When you say "I tried to instantiate tasks using the type of the original struct, but couldn't get it working." what was the error and how did you do it? Was tasks of type []MyInterface of []MyStructType? Commented Feb 21, 2013 at 14:41
  • @JimPaek: Sry, that was poorly written: I just tried to figure out how to instantiate the structs original type. And found no way. (What I wanted was MyStructType). Commented Feb 21, 2013 at 14:46

1 Answer 1

1

mgo can't create MyInterface objects since MyInterface is just an interface. Try doing :

myObject := &MyInterface{}  //fails

I think it's basically what mgo is trying to do for each record it tries to unmarshal.

To achieve what you want, make tasks of type []map[string]interface{} or []bson.M (the latter is an alias for the former) and then:

for _, o := range tasks {
    t := &MyTypeThatImplementsMyInterface{ 
        Field1 : o["my_field"],
        //etc.  
    } 
    t.Do()
}

Either that or make tasks a slice of objects of a type (var tasks []MyStructType) that implements MyInterface and that its fields match the keys and values types of your bson objects in your database. That might not work if your stored data is of more than one type implementing MyInterface, hence the slice of maps option above.

Also, be cautious with Find(nil).All(&tasks). If you have millions of records in that collection, depending on the records size, you may fall short of memory.

Sign up to request clarification or add additional context in comments.

2 Comments

I see. Yeah, there are a lot of unknown types that implement that interface (I mean, that's what interfaces are for...). Does that mean, there is solution to my problem? Or can I somehow dynamically create MyTypeThatImplementsMyInterface structs?
Consider using an iterator godoc.org/labix.org/v2/mgo#Iter. You could retrieve each record in a bson.M object, then test the presence of fields and then create a concrete object from them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.