How do I iterate over `*[]struct` in golang?

huangapple go评论110阅读模式
英文:

How do I iterate over `*[]struct` in golang?

问题

我正在动态创建结构体,并将CSV文件解组到结构体中。解组后,我得到了类型为*[]struct{}的填充变量。我可以使用fmt.Printf("%v", theVariable)打印所有值,结果为&[{} {}]。我该如何遍历它?

代码片段:

f, err := os.Open(csvFile)
if err != nil {
	panic(err)
}
defer f.Close()

instance := dynamicstruct.NewStruct().
		AddField("Integer", 0, `csv:"int"`).
		AddField("Text", "", `csv:"someText"`).
		AddField("Float", 0.0, `csv:"double"`).
		Build().
		NewSliceOfStructs()

if err := gocsv.Unmarshal(f, instance); err != nil {
	utils.Capture(errors.Chain(err, "Unable to unmarshal csv file"), true)
}

请注意,我只翻译了你提供的代码部分。

英文:

I am dynamically creating structs and unmarshaling csv file into the struct. After unmarshaling I get the populated variable of type *[]struct{}. I am able to to a fmt.Printf("%v", theVarible) and see all the values printed as &[{} {}] . How do I loop over this?

code snippet :

f, err := os.Open(csvFile)
if err != nil {
	panic(err)
}
defer f.Close()

instance := dynamicstruct.NewStruct().
		AddField("Integer", 0, `csv:"int"`).
		AddField("Text", "", `csv:"someText"`).
		AddField("Float", 0.0, `csv:"double"`).
		Build().
		NewSliceOfStructs()

if err := gocsv.Unmarshal(f, instance); err != nil {
	utils.Capture(errors.Chain(err, "Unable to unmarshal csv file"), true)
}

答案1

得分: 3

使用reflect包来访问动态定义的切片类型的元素:

instance := dynamicstruct.NewStruct().
    AddField("Integer", 0, `csv:"int"`).
    AddField("Text", "", `csv:"someText"`).
    AddField("Float", 0.0, `csv:"double"`).
    Build().
    NewSliceOfStructs()

if err := gocsv.Unmarshal(f, instance); err != nil {
    utils.Capture(errors.Chain(err, "Unable to unmarshal csv file"), true)
}

// instance中的具体值是指向切片的指针。创建反射值并使用Elem()进行间接操作,以获取切片的反射值。
slice := reflect.ValueOf(instance).Elem()

// 对于切片的每个元素...
for i := 0; i < slice.Len(); i++ {

    // slice.Index(i)是元素的反射值。
    element := slice.Index(i)

    // element.FieldByName返回具有给定名称的字段的反射值。调用Interface()以获取实际值。
    fmt.Println(element.FieldByName("Integer").Interface(),
        element.FieldByName("Text").Interface(),
        element.FieldByName("Float").Interface())
}

[ Playground 上运行示例](https://play.golang.org/p/CCn9Zy2AJTP)。
英文:

Use the reflect package to access the elements of a dynamically defined slice type:

instance := dynamicstruct.NewStruct().
	AddField(&quot;Integer&quot;, 0, `csv:&quot;int&quot;`).
	AddField(&quot;Text&quot;, &quot;&quot;, `csv:&quot;someText&quot;`).
	AddField(&quot;Float&quot;, 0.0, `csv:&quot;double&quot;`).
	Build().
	NewSliceOfStructs()

if err := gocsv.Unmarshal(f, instance); err != nil {
    utils.Capture(errors.Chain(err, &quot;Unable to unmarshal csv file&quot;), true)
}

// The concrete value in instance is a pointer to 
// the slice of structs. Create the reflect value 
// and indirect with Elem() to get the reflect value
// for the slice.
slice := reflect.ValueOf(instance).Elem()

// For each element of the slice...
for i := 0; i &lt; slice.Len(); i++ {

    // slice.Index(i) is the reflect value for the
    // element.  
	element := slice.Index(i)

    // element.FieldByName returns the reflect value for 
    // the field with the given name.  Call Interface()
    // to get the actual value.
	fmt.Println(element.FieldByName(&quot;Integer&quot;).Interface(),
		element.FieldByName(&quot;Text&quot;).Interface(),
		element.FieldByName(&quot;Float&quot;).Interface())
}

Run an example on the Playground.

huangapple
  • 本文由 发表于 2021年6月23日 13:20:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/68093894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定