为了账号安全,请及时绑定邮箱和手机立即绑定

如何将结构转换为平面路径数组?

如何将结构转换为平面路径数组?

Go
精慕HU 2022-10-10 19:13:06
例如,如果我有一个结构,例如:type Example struct {   Foo string   Bar string   Baz struct{     A int     B string   }   Qux []string}将其转换为表示每个结构字段的点路径的扁平字符串切片的最佳方法是什么?我想要一个类似于以下切片的输出:["Example.Foo", "Example.Bar", "Example.Baz.A", "Example.Baz.B", "Example.Qux.0", "Example.Qux.1"]确切的结构将在编译时知道。此外,从结构到平面列表的转换处于热门路径,因此性能将是一个重要的考虑因素。任何提示将不胜感激!
查看完整描述

1 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

您必须自己编写代码,并进行反思。


这是一个演示函数,可打印您提供的输出:


package main


import (

"fmt"

    "reflect"

    "strconv"

)


type Example struct {

    Foo string

    Bar string

    Baz struct{

        A int

        B string

    }

    Qux []string

}


func main() {

    example := Example{Qux: []string{"a", "b"}}

    t := reflect.ValueOf(example)

    prefix := t.Type().Name()

    fmt.Println(ToPathSlice(t, prefix, make([]string, 0)))

}


func ToPathSlice(t reflect.Value, name string, dst []string) []string {

    switch t.Kind() {

    case reflect.Ptr, reflect.Interface:

        return ToPathSlice(t.Elem(), name, dst)


    case reflect.Struct:

        for i := 0; i < t.NumField(); i++ {

            fname := t.Type().Field(i).Name

            dst = ToPathSlice(t.Field(i), name+"."+fname, dst)

        }


    case reflect.Slice, reflect.Array:

        for i := 0; i < t.Len(); i++ {

            dst = ToPathSlice(t.Index(i), name+"."+strconv.Itoa(i), dst)

        }


    default:

        return append(dst, name)

    }

    return dst

}

将打印:

[Example.Foo Example.Bar Example.Baz.A Example.Baz.B Example.Qux.0 Example.Qux.1]

注意:

  • 反射会带来性能损失;如果您对此感到担忧,您应该分析相关的代码路径以查看它是否会破坏交易

  • 上面的代码是人为的,例如它不处理地图,它不处理nil等等;你可以自己扩展它

  • 在您想要的输出中,将打印切片/数组字段的索引。切片没有数组的固有长度。为了知道切片的长度,您必须使用reflect.Value. 这个 IMO 使代码更加尴尬。如果您可以接受不打印切片索引,那么您可以使用reflect.Type.

游乐场: https: //play.golang.org/p/isNFSfFiXOP




查看完整回答
反对 回复 2022-10-10
  • 1 回答
  • 0 关注
  • 165 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号