使用基础类型

时间:2017-08-13 22:41:16

标签: go sqlx

我使用本机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
}

...但是我需要构建一个接受接口{}并返回[]接口{}的泛型函数。我发现更换上面的行var a Account的过程很困难,因为它需要在复制其基础类型时制作传入的接口{}类型的副本。我是否应该让自己屈服于我需要使用反射的事实,还是有其他方法可以做到这一点?

2 个答案:

答案 0 :(得分: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
*/

答案 1 :(得分:0)

首先,您在描述中提到的内容与现在之间似乎存在差异

  

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

以及您的代码所做的事情(它接受一个接口片而不是接口)。

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

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

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

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