duanlu1959 2017-04-17 17:34
浏览 74


I have two structs at the moment.

type One struct {
    Name  string
    Age   int
    ID    int
    Owner string

type Two struct {
    ID    int
    Make  string
    Bags  string
    Age   int
    Owner string

These structs map to a table in a DB, I use an interface to provide access to the DB and contents. In this case just a listing of the data in One and Two based on the owner.

type dbInterface interface {
    ListOnesByOwner(owner string) ([]*One, error)
    LitsTwosByOwner(owner string) ([]*Two, error)

The listing functions are the same except for the structs.

func (db *DB) ListOnes(owner string) ([]*One, error) {
    ones = make([]*One, 0)
    q := db.NewQuery("One").
        Filter("Owner =", owner).

    keys, err := db.client.GetAll(q, &ones)
    for i, k := range keys {
        ones[i].ID = k.ID
    return ones, nil

func (db *DB) ListTwos(owner string) ([]*Two, error) {
    twos = make([]*Two, 0)
    q := db.NewQuery("Two").
        Filter("Owner =", owner).

    keys, err := db.client.GetAll(q, &twos)
    for i, k := range keys {
        twos[i].ID = k.ID
    return twos, nil

func main() {
    ones, err := DB.ListOnesByOwner(user.ID)
    twos, err := DB.ListTwosByOwner(user.ID)

I'm fairly new to GO, so I'm wondering what is the idiomatic way to reduce the code duplication seen here? If I was to add a couple more structs then it would be unwieldy because the amount of code duplication needed.

Thanks for any help!

  • 写回答

2条回答 默认 最新

  • dongzangchui2072 2017-04-17 19:31

    Assuming that db.client.GetAll takes an interface{} as its second argument, which it appears to, you can in fact DRY it out:

    func (db *DB) dryGet(owner, table string, result interface{}) error {
        q := db.NewQuery(table).Filter("Owner =", owner).Order("Name")
        keys,err := db.client.GetAll(q, &result)
        return err

    Converting the result to a map is a little more difficult because Go lacks generics, and your structs have no methods that could be used to interface them. It's possible but would require, at the least, creating a getID method on each type, creating a hasID interface, and then returning a map[int]hasID, which the caller would then have to cast the values of back to the struct type to access any other fields. Not optimal, but doable. However, the above solution would at least let you eliminate a good portion of duplicate code.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?



  • ¥30 代码本地运行正常,但是TOMCAT部署时闪退
  • ¥15 关于#python#的问题
  • ¥15 主机可以ping通路由器但是连不上网怎么办
  • ¥15 数据库一张以时间排好序的表中,找出多次相邻的那些行
  • ¥50 关于DynamoRIO处理多线程程序时候的问题
  • ¥15 kubeadm部署k8s出错
  • ¥15 Abaqus打不开cae文件怎么办?
  • ¥20 双系统开机引导中windows系统消失问题?
  • ¥15 小程序准备上线,软件开发公司需要提供哪些资料给甲方
  • ¥15 关于生产日期批次退货退款,库存回退的问题