登录
首页 >  Golang >  Go问答

将结构转化为二维路径数组的步骤

来源:stackoverflow

时间:2024-02-24 22:00:25 257浏览 收藏

本篇文章向大家介绍《将结构转化为二维路径数组的步骤》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。

问题内容

例如,如果我有一个结构,例如:

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"]

确切的结构将在编译时得知。此外,从结构到平面列表的转换处于热路径中,因此性能将是一个重要的考虑因素。

如有任何提示,我们将不胜感激!


正确答案


您必须通过反射自己编写代码。

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

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

本篇关于《将结构转化为二维路径数组的步骤》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>