在当前项目中,我们通过mgo驱动程序使用Go和MongoDB。 对于每个实体,我们必须为CRUD操作实现DAO,并且它基本上是复制粘贴,例如
func (thisDao ClusterDao) FindAll() ([]*entity.User, error) {
session, collection := thisDao.getCollection()
defer session.Close()
result := []*entity.User{} //create a new empty slice to return
q := bson.M{}
err := collection.Find(q).All(&result)
return result, err
}
对于其他所有实体,它只是结果类型。
由于Go没有泛型,我们怎么能避免代码重复?
我试图传递result interface{}
param而不是在方法中创建它,并调用这样的方法:
dao.FindAll([]*entity.User{})
但是collection.Find().All()
方法需要一个切片作为输入,而不仅仅是接口:
[restful] recover from panic situation: - result argument must be a slice address
/usr/local/go/src/runtime/asm_amd64.s:514
/usr/local/go/src/runtime/panic.go:489
/home/dds/gopath/src/gopkg.in/mgo.v2/session.go:3791
/home/dds/gopath/src/gopkg.in/mgo.v2/session.go:3818
然后我尝试制作这个参数result []interface{}
,但在这种情况下,我无法通过[]*entity.User{}
:
不能在[thisDao.GenericDao.FindAll
的参数中使用[] * entity.User literal(type [] * entity.User)作为类型[] interface {}
任何想法如何在Go中实现通用DAO?
答案 0 :(得分:1)
您应该能够将result interface{}
传递给FindAll
函数,然后将其传递给mgo的Query.All方法,因为参数会有func (thisDao ClusterDao) FindAll(result interface{}) error {
session, collection := thisDao.getCollection()
defer session.Close()
q := bson.M{}
// just pass result as is, don't do & here
// because that would be a pointer to the interface not
// to the underlying slice, which mgo probably doesn't like
return collection.Find(q).All(result)
}
// ...
users := []*entity.User{}
if err := dao.FindAll(&users); err != nil { // pass pointer to slice here
panic(err)
}
log.Println(users)
同类型。
List<int>() numbers = new List<int>();
int num;
while(int.TryParse(Console.ReadLine(), out num))
{
numbers.Add(num);
}