Golang:有没有一种方法可以使用反射以通用的方式迭代切片



有没有一种方法可以使用反射以通用的方式迭代切片?

type LotsOfSlices struct {
As []A
Bs []B
Cs []C
//.... and lots more of these
}
type A struct {
F string
//.... and lots of other stufff that's different from the other structs
}
type B struct {
F string
//.... and lots of other stufff that's different from the other structs
}
type C struct {
F string
//.... and lots of other stufff that's different from the other structs
}

我想使用反射来减少代码的复杂性和重复代码。这可能吗?这是个坏主意吗?

例如,不是这个:

func processData(l LotsOfSlice){
for _, a := range l.As{
// use a.F
}
for _, b := range l.Bs{
// use b.F
}
for _, c := range l.Cs{
// use c.F
}
...
}

但取而代之的是这样的东西:

func processData(l LotsOfSlices){
t := reflect.TypeOf(l)
for i := 0; i < t.NumField(); i++ {
zs := reflect.ValueOf(l).Field(i).Interface()
for _, z := range zs{
// use z.F
}
}
}

使用Value.Len和Value.Index迭代数组或切片:

func processData(l LotsOfSlices) {
v := reflect.ValueOf(l)
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if f.Kind() != reflect.Slice {
continue
}
for i := 0; i < f.Len(); i++ {
e := f.Index(i)
s := e.FieldByName("F")
// Do something with s
}
}
}

如果您的结构执行类似的最终结果(返回int或对字符串进行运算(,但对于每个结构类型都是唯一的,则可以在它们上定义函数:

func (a *A) GetResult() int { // sums two numbers
return a.p1 + a.p2
}
func (b *B) GetResult() int { // subtracts two numbers
return b.p1 - b.p2
}
func (c *C) GetResult() int { // times two numbers
return c.p1 * c.p2
}

然后定义一个接口Operable

type Operable interface {
GetResult() int // shared function
}

然后创建一个接受接口作为参数的函数,并且任何实现该接口中所有函数的结构都可以作为参数被接受

func processOperable(o []Operable){
for _, v := range o{
v.GetResult() --> unique for each struct
}
}

最新更新