我使用本机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
的过程很困难,因为它需要在复制其基础类型时制作传入的接口{}类型的副本。我是否应该让自己屈服于我需要使用反射的事实,还是有其他方法可以做到这一点?
答案 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
。