猿问

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

        }

    }

}


心有法竹
浏览 161回答 2
2回答

冉冉说

使用Value.Len和Value.Index迭代数组或切片:func processData(l LotsOfSlices) {&nbsp; &nbsp; v := reflect.ValueOf(l)&nbsp; &nbsp; for i := 0; i < v.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; f := v.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; if f.Kind() != reflect.Slice {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < f.Len(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e := f.Index(i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s := e.FieldByName("F")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Do something with s&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

茅侃侃

如果您的结构执行类似的最终结果(返回 int 或对字符串进行操作)但对于每种结构类型都是唯一的,您可以在它们上定义函数:func (a *A) GetResult() int { // sums two numbers&nbsp; &nbsp; return a.p1 + a.p2}func (b *B) GetResult() int { // subtracts two numbers&nbsp; &nbsp; return b.p1 - b.p2}func (c *C) GetResult() int { // times two numbers&nbsp; &nbsp; return c.p1 * c.p2}然后定义一个接口Operabletype Operable interface {&nbsp; &nbsp; GetResult() int // shared function}然后创建一个接受接口作为参数的函数,并且任何实现该接口中所有函数的结构都可以作为参数被接受func processOperable(o []Operable){&nbsp; &nbsp; for _, v := range o{&nbsp; &nbsp; &nbsp; &nbsp; v.GetResult() --> unique for each struct&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答