将不同的结构体传递给一个函数(GO)?

huangapple go评论80阅读模式
英文:

Passing different structs to a function (GO)?

问题

我有一个类似以下代码的函数用于查询Mongo数据库:

func findEntry(db, table string, entry *User, finder *bson.M) (err error) {
    c := mongoSession.DB(db).C(table)
    return c.Find(finder).One(entry)
}

我想要重用这个函数来查询除了"User"之外的其他结构体,通过传递一个指向任何实例化结构体对象的指针来实现,但我不确定如何正确使用语义。我认为我可以通过将entry参数设置为interface{},然后使用反射将其"转换"回原始结构体,以便在调用时One()函数能正确填充结构体。有没有更好的方法来实现这个(请不要批评缺乏泛型,我只是在寻找使用最佳实践的实际解决方案)。

英文:

I have a function like the following for querying a mongo database:

func findEntry(db, table string, entry *User, finder *bson.M) (err error) {
    c := mongoSession.DB(db).C(table)
    return c.Find(finder).One(entry)
}

I'd like to reuse the function for structs other than "User", by passing in a pointer to any instantiated struct object - just not quite sure of the proper semantics to do this. I think that I should be able to do this by making the 'entry' parameter an interface{} and then I'd need to use reflection to 'cast' it back to the original struct so the One() function call could properly fill in the struct on the call? Is there a 'better' way to accomplish this (please no flaming about lack of generics, I'm just looking for a practical solution using best practices).

答案1

得分: 4

使用以下函数:

func findEntry(db, table string, entry interface{}, finder bson.M) error {
    c := mongoSession.DB(db).C(table)
    return c.Find(finder).One(entry)
}

并像这样调用它:

var user User
err := findEntry("db", "users", &user, bson.M{"name": "John"})

user 的类型信息通过 findEntry 传递给了 One 方法。在 findEntry 中不需要使用反射或者“转换”。

此外,使用 bson.M 而不是 *bson.M。在这里不需要使用指针。

我在 playground 上创建了一个示例,展示了类型信息是如何通过 findEntry 传递的。

英文:

Use this function:

func findEntry(db, table string, entry interface{}, finder bson.M) error {
    c := mongoSession.DB(db).C(table)
    return c.Find(finder).One(entry)
}

and call it like:

var user User
err := findEntry("db", "users", &user, bson.M{"name": "John"})

The type information for user is passed through findEntry to the One method. There's no need for reflection or a "cast" in findEntry.

Also, use bson.M instead of *bson.M. There's no need to use a pointer here.

I created an example on the playground to show that the type information is passed through findEntry.

huangapple
  • 本文由 发表于 2014年12月15日 21:42:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/27485429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定