Iterate through struct in golang without reflect

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

Iterate through struct in golang without reflect

问题

我有一个类似这样的结构体:

import (
    "fmt"
)

type Node struct {
    m []string
    o []string
}

func main() {

    var mm = []string{"abc", "def"}
    var oo = []string{"111", "222"}

    var v = Node{m: mm, o: oo}

    for i := 0; i < len(v.m); i++ {
        fmt.Println(v.m[i] + "," + v.o[i])
    }

}

我得到的输出是:

[abc def]
[111 222]

我希望得到的输出是:

abc,111
def,222

我不想使用 reflect 包,因为我尽可能想使用原生的 Go 内置功能。如果这变得太麻烦,我会退回到 reflect 包。

英文:

I have a struct like this

import (
        &quot;fmt&quot;
)

type Node struct {
        m []string
        o []string
}

func main() {

        var mm = []string{&quot;abc&quot;, &quot;def&quot;}
        var oo = []string{&quot;111&quot;, &quot;222&quot;}

        var v = Node{m: mm, o: oo}

        for _, d := range []interface{}{v.m, v.o} {
                fmt.Println(d)
        }

}

The output I get is,

[abc def]
[111 222]

My desired output is,

abc,111
def,222

I don't want to use reflect package because, I want to use native go built-ins as much as possible. If it becomes too burdensome I will fall back on reflect package.

答案1

得分: 1

你不想使用reflect包的原因是什么?像这个问题https://stackoverflow.com/questions/18926303/iterate-through-a-struct-in-go和https://stackoverflow.com/questions/21246642/iterate-over-string-fields-in-struct这样的问题?

从前一个问题来看,似乎是的,你可以通过迭代字段的interface来实现无需使用reflect进行迭代,示例代码如下:

package main

import (
	"fmt"
)

type Foo struct {
	num int
	str string
}

func main() {
	foo := &Foo{42, "Hello"} // struct with fields of many types...
	for _, data := range []interface{}{foo.num, foo.str} {
		fmt.Println(data)
	}
}

希望对你有帮助!

英文:

Is there a reason you don't want to use the reflect package? like https://stackoverflow.com/questions/18926303/iterate-through-a-struct-in-go and https://stackoverflow.com/questions/21246642/iterate-over-string-fields-in-struct ?

From the former question, it seems like, yeah you can iterate without reflect by iterating through an interface of the fields, https://play.golang.org/p/bPWUII_D7q

package main

import (
    &quot;fmt&quot;
)

type Foo struct {
    num int
    str string
}

func main() {
    foo := &amp;Foo{42, &quot;Hello&quot;} // struct with fields of many types...
    for _, data := range []interface{}{foo.num, foo.str} {
	    fmt.Println(data)
    }
}

答案2

得分: 1

**编辑:**我刚意识到我的输出与你的不匹配,你是否希望字母与数字配对?如果是的话,你需要重新调整你的代码。

你可以使用strings.Join和类型切换语句来实现:

package main

import (
	"fmt"
	"strings"
)

type Node struct {
	m []string
	o []string
	p []int
}

func main() {

	var mm = []string{"abc", "def"}
	var oo = []string{"111", "222"}
	var pp = []int{1, 2, 3}

	var v = Node{m: mm, o: oo, p: pp}

	for _, d := range []interface{}{v.m, v.o, v.p} {
		switch d.(type) {
		case []string:
			fmt.Println(strings.Join(d.([]string), ","))
		default:
			fmt.Println(d)
		}
	}

}

输出结果为:

abc,def
111,222
[1 2 3]
英文:

Edit: I just realized my output doesn't match yours, do you want the letters paired with the numbers? If so then you'll need to re-work what you have.

You can use strings.Join and a type switch statement to accomplish this:

https://play.golang.org/p/ygtdxv02uK

package main

import (
	&quot;fmt&quot;
	&quot;strings&quot;
)

type Node struct {
	m []string
	o []string
	p []int
}

func main() {

	var mm = []string{&quot;abc&quot;, &quot;def&quot;}
	var oo = []string{&quot;111&quot;, &quot;222&quot;}
	var pp = []int{1, 2, 3}

	var v = Node{m: mm, o: oo, p: pp}

	for _, d := range []interface{}{v.m, v.o, v.p} {
		switch d.(type) {
		case []string:
			fmt.Println(strings.Join(d.([]string), &quot;,&quot;))
		default:
			fmt.Println(d)
		}
	}

}

The output is:

abc,def
111,222
[1 2 3]

答案3

得分: 0

这是我所做的:

package main

import (
	"fmt"
)

type Node struct {
	m []string
	o []string
}

func main() {

	var mm = []string{"abc", "def"}
	var oo = []string{"111", "222"}

	var v = Node{m: mm, o: oo}

	for i := range v.m {
		fmt.Println(v.m[i], v.o[i])
	}
}

这给我提供了我想要的输出。只有一件事,我必须写v.m,所以我想我仍然应该使用reflect包。

英文:

Here is what I did,

package main

import (
        &quot;fmt&quot;
)

type Node struct {
        m []string
        o []string
}

func main() {

        var mm = []string{&quot;abc&quot;, &quot;def&quot;}
        var oo = []string{&quot;111&quot;, &quot;222&quot;}

        var v = Node{m: mm, o: oo}

        for i := range v.m {
                fmt.Println(v.m[i],v.o[i])
        }
}

This gives me my desired output. Just one thing is I have to write v.m so I suppose I should still use reflect package.

huangapple
  • 本文由 发表于 2017年1月19日 00:30:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/41724608.html
匿名

发表评论

匿名网友

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

确定