通过go结构迭代获取csv字符串

时间:2017-09-25 05:20:14

标签: go

我有一个表示数据集的结构,我需要将其作为时间序列数据写入CSV文件。这是我到目前为止所做的。

type DataFields struct {
    Field1 int,
    Field2 string,
    ...
    Fieldn int
}

func (d DataFields) String() string {
    return fmt.Sprintf("%v,%v,...,%v", Field1, Field2,..., Fieldn)
}

有没有办法可以迭代结构的成员并使用它构造一个字符串对象?

性能在这里确实不是一个问题,我想知道是否有一种方法可以生成字符串而不必修改String()函数,如果结构将来发生变化。

编辑以在下面添加我的更改:

这是我在查看下面的答案后最终得到的结果。

func (d DataFields) String() string {
    v := reflect.ValueOf(d)
    var csvString string
    for i := 0; i < v.NumField(); i++ {
        csvString = fmt.Sprintf("%v%v,", csvString, v.Field(i).Interface())
    }

    return csvString
}

3 个答案:

答案 0 :(得分:2)

您要找的是reflectionThis回答解释了如何使用它来循环结构并获取值。

这是作者在另一个答案中使用的例子:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    x := struct{Foo string; Bar int }{"foo", 2}
    v := reflect.ValueOf(x)
    values := make([]interface{}, v.NumField())

    for i := 0; i < v.NumField(); i++ {
        values[i] = v.Field(i).Interface()
    }

    fmt.Println(values)
}

您可以在go playground上看到它。

答案 1 :(得分:1)

一种方法是使用reflect包。有一种Value.Field(int) Value方法可能对您有用。您基本上首先使用DataField调用ValueOf(interface{}) Value,然后在Field(int) Value上调用Value进行简单循环。

答案 2 :(得分:0)

另一种方法是使用code generation来为您生成序列化代码。

权衡取舍是:

  • Codegen更加强化,因为它大部分时间都依赖于它 关于运行外部程序(虽然这可以通过以下方式更简单) 使用go run,因为它应该始终可用。)

    每次更改数据类型时都会添加或删除 必须序列化的字段,您需要运行go generate 重新生成序列化程序代码。

    另一方面,生成的代码快速而强大, 而且数据类型的变化通常很少。

  • 反思更简单,因为它不需要考虑 重新生成代码。

    另一方面,使用reflect的代码通常是丑陋的,很难理解。当然,它会导致运行时性能损失。