0

我正在使用本地 sql 库和 jmoiron/sqlx 从 postgres 数据库填充结构列表。我目前有针对不同类型的单独功能,例如:

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
}

...但我需要构建一个接受 interface{} 并返回 []interface{} 的通用函数。我发现替换上述行的过程var a Account很困难,因为它需要在复制其基础类型时复制传入的 interface{} 类型。我应该接受我需要使用反射的事实,还是有其他方法可以做到这一点?

4

2 回答 2

0

首先,到目前为止,您在描述中提到的内容似乎有所不同

但我需要构建一个接受 interface{} 并返回 []interface{} 的通用函数。

以及您的代码的作用(它接受接口的一部分而不是接口)。

您可能不需要像您的代码当前那样在函数参数中接受一部分接口,可以只接受一个接口,因此您的函数可以如下所示:

func selectAccounts(ext sqlx.Ext, query string, args interface{}) ([]Account, error) {

您可以返回一片接口并在其中包含任何类型。请看看这个https://play.golang.org/p/NcLxhsiqK8

正如@ivan.sim 所提到的,您可以只附加Account到接口切片而不是创建切片Accounts

于 2017-08-14T04:18:01.567 回答
0

你不能让你的结构多态并让它们实现一个接口吗?那么你的函数可以返回一部分所述接口吗?这样你就不必使用反射了。我在想一些事情:

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
*/
于 2017-08-14T02:39:49.053 回答