2017-04-03 4 views
1

現在のプロジェクトでは、GoとMongoDBをmgoドライバで使用しています。 すべてのエンティティについて、CRUD操作にDAOを実装する必要があります。基本的にはコピー貼り付けです。GoとMongoDB:汎用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にジェネリックスがないので、コードの重複を避けるにはどうすればよいですか?

dao.FindAll([]*entity.User{}) 

しかしcollection.Find().All()方法の入力だけではないインターフェイスとしてのスライスを必要とする:

は、私が代わりの方法でそれを作成するのでresult interface{}のparamを渡し、このようなメソッドを呼び出すために試してみました:

[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 

は、その後、私はこのPARAM result []interface{}を作ってみましたが、その場合にはそれが[]*entity.User{}に合格することは不可能です:

は、[] * entity.Userリテラル([] * entity.User型)

私は一般的な実装できる方法の任意のアイデアをthisDao.GenericDao.FindAllする引数を入力し、[]はインターフェイス{}として使用できませんGoのDAO?

答えて

1

FindAll関数にresult interface{}を渡して、引数の型が同じであるため、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) 
+0

いいえ、動作しません。結果: '[restful]はパニック状況から回復する: - 結果引数はスライスアドレスでなければならない。 /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' – dds

+0

あなたのサンプルコードでは、スライスへのポインタを渡していません。 'dao.FindAll( [] * entity.User {}) '< - これがエラーを起こす理由です。これはスライスへのポインタではなく、User構造体へのポインタのスライスです。私の例では、これを指摘するためにコメントを追加しました...私の例でコードをテストしただけで動作します。あなたがスライスへのポインタを渡していると確信しているなら、あなたのコードをもっと共有してください。 – mkopriva

+0

@ddsここにその例がありますhttp://imgur.com/dbKWJZB – mkopriva