【问题标题】:Passing different structs to a function (GO)?将不同的结构传递给函数(GO)?
【发布时间】:2014-12-15 13:42:04
【问题描述】:

我有如下函数用于查询 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)
}

我想通过传入一个指向任何实例化结构对象的指针来为“用户”以外的结构重用该函数——只是不太确定执行此操作的正确语义。我认为我应该能够通过将“入口”参数设置为 interface{} 来做到这一点,然后我需要使用反射将其“转换”回原始结构,以便 One() 函数调用可以正确填充在调用结构中?有没有“更好”的方法来实现这一点(请不要因为缺乏泛型而生气,我只是在寻找使用最佳实践的实用解决方案)。

【问题讨论】:

  • 你就是这样做的,别无他法 :) 也不要对成语大发雷霆。
  • 如果你的函数真的只有一行长(跨越两行):为什么不拥有几个这样的函数,比如 findUser findOther、findSomethingElse...?

标签: go mgo


【解决方案1】:

使用此功能:

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。此处无需使用指针。

我创建了an example on the playground来显示类型信息是通过findEntry传递的。

【讨论】:

  • entry 需要像这样断言 val, ok := entry.(*User)。然后将该 val 发送到 One 方法中
  • @Minty 不需要类型断言。运行this playground example 可以看到类型信息通过类似于 OP 的 findEntry 函数的函数传递的演示。
  • 如果您使用的是 fmt 包,则为 true。但是,如果您使用第三方 API,例如上面使用的 API,该怎么办?它需要引用具体结构来“解组”数据。
  • 哦,我明白了。我不知道这个 API 在后台使用了反射。那么是的,对于这个例子,你不需要断言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-12
  • 2012-05-09
  • 2013-10-19
相关资源
最近更新 更多