首页 文章

Golang用struct值填充函数参数

提问于
浏览
0

我想知道是否有一种方法可以在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())

1 回答

  • 2

    这可以使用 reflect 包完成,它允许您循环结构的字段,然后构造一个 driver.Value 的片 . 然后,您将生成的切片传递给 AddRow ,并将内容尾随 ... 传递给"unpack" .

    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() 返回的类型也是如此 .

    https://play.golang.org/p/7Oy8_YrmkMa

相关问题