我想知道是否有一种方法可以在golang中使用结构的所有值(通常是不同类型的值)填充可变参数函数参数。
我想到的具体示例是以下代码段,使用https://github.com/DATA-DOG/go-sqlmock为模拟的postgres数据库查询生成一行:
rows := sqlmock.NewRows([]string{
"id",
"updated_at",
"created_at",
"meta",
"account_id",
"currency",
"nickname",
"scheme_name",
"identification",
"name",
"identification_secondary",
"servicer_scheme_name",
"servicer_identification",
"institution_id",
"client_id",
}).AddRow(
mock.Values.AccountID,
time.Now(),
time.Now(),
"{}",
"12345678",
"GBP",
"Test",
"Schema",
"12345676534263",
"New account",
"12345",
"schema",
"test id",
mock.Values.InstitutionID,
mock.Values.ClientID,
)
鉴于参数总是表示结构(字段和值),我试图使用结构来填充字段和值,而不是手动完成每个。使用反射字段相当简单,但是值为多种类型,AddRow函数定义为:
AddRow func(values ...driver.Value) *Rows
有没有办法循环结构字段并提供类型化值来实现类似?...
account := Account{
ID: "ABCD12436364",
UpdatedAt: time.Now(),
CreatedAt: time.Now(),
Meta: "{}",
AccountID: "12345678",
Currency: "GBP",
Nickname: "Test",
SchemeName: "Scheme",
Identification: "12345676534263",
Name: "New account",
IdentificationSecondary: "12345",
ServicerSchemeName: "scheme",
ServicerIdentification: "test id",
InstitutionID: "ABCD123456",
ClientID: "ZXCVB12436",
}
rows := sqlmock.NewRows(account.GetFieldsJSON()).AddRow(account.GetValues())
答案 0 :(得分:2)
这可以使用reflect
包来完成,它允许你循环结构的字段,然后构造一个driver.Value
的片段。然后,您将结果切片传递给AddRow
,并使用尾随...
来“解压缩”内容。
var result []driver.Value
rv := reflect.ValueOf(account)
for i := 0; i < rv.NumField(); i++ {
fv := rv.Field(i)
dv := driver.Value(fv.Interface())
result = append(result, dv)
}
AddRow(result...)
请注意,在这种情况下,转化driver.Value(fv.Interface())
有效,因为driver.Value
是一个空接口,fv.Interface()
返回的类型也是如此。