duanlu1959 2017-04-17 17:34
浏览 74
已采纳

Golang避免代码重复

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).
        Order("Name")

    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).
        Order("Name")

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格