douzhu1188 2017-08-13 22:41
浏览 4

复制具有基本类型的interface {}参数

I am populating lists of structs from a postgres database using the native sql library and jmoiron/sqlx. I currently have separate functions for different types, for example:

func selectAccounts(ext sqlx.Ext, query string, args []interface{}) ([]Account, error) {
    var accts []Account
    rows, err := ext.Queryx(query, args...)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    for rows.Next() {
        var a Account
        if err = rows.StructScan(&a); err != nil {
            return nil, err
        }
        accts = append(accts, a)
    }
    err = rows.Err()
    return accts, err
}

... but I have a requirement to build a generic function that accepts interface{} and returns a []interface{}. I am finding the process of replacing the line var a Account above is difficult, as it requires making a copies of the passed in interface{} type while replicating its underlying type. Should I resign myself to the fact that I need to be using reflection, or is there another way to go about doing this?

  • 写回答

2条回答 默认 最新

  • duanchun1909 2017-08-14 02:39
    关注

    Couldn't you make your structs polymorphic and have them implement a single interface? Then your function can return a slice of said interface? This way you wouldn't have to use reflection. I was thinking something along these lines:

    package main
    
    import (
        "fmt"
    )
    
    type Account interface {
        GetDetails() string
    }
    
    type PersonAccount struct {
        Name string
    }
    
    func NewPersonAccount(name string) Account {
        return &PersonAccount{
            Name: name,
        }
    }
    
    func (account *PersonAccount) GetDetails() string {
        return account.Name
    }
    
    type BillingAccount struct {
        AccountNumber string
    }
    
    func NewBillingAccount(accountNumber string) Account {
        return &BillingAccount{
            AccountNumber: accountNumber,
        }
    }
    
    func (account *BillingAccount) GetDetails() string {
        return account.AccountNumber
    }
    
    func getAllAccounts() []Account {
        accounts := make([]Account, 0)
        accounts = append(accounts, NewPersonAccount("John Doe"))
        accounts = append(accounts, NewBillingAccount("1234-5678"))
    
        return accounts
    }
    
    func main() {
        accounts := getAllAccounts()
    
        for _, account := range accounts {
            fmt.Println(account.GetDetails())
        }
    }
    
    /* Output:
    John Doe
    1234-5678
    */
    
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?