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

如何按字母顺序对结构字段进行排序

如何按字母顺序对结构字段进行排序

Go
摇曳的蔷薇 2021-10-18 10:59:19
如何获得按字段排序的结构输出?type T struct {    B int    A int}t := &T{B: 2, A: 1}doSomething(t)fmt.Println(t)  // &{1 2} --> Sorted by fields
查看完整描述

2 回答

?
大话西游666

TA贡献1817条经验 获得超14个赞

Astruct是字段的有序集合。该fmt包使用反射来获取值的字段和值struct,并按照定义的顺序生成输出。


因此,最简单的解决方案是声明您的类型,其中您已经按字母顺序排列了您的字段:


type T struct {

    A int

    B int

}

如果你不能修改字段的顺序(例如内存布局很重要),你可以Stringer通过String()为你的结构类型指定一个方法来实现接口:


func (t T) String() string {

    return fmt.Sprintf("{%d %d}", t.A, t.B)

}

该fmt包检查传递的值是否实现Stringer,如果实现,则调用其String()方法来生成输出。


该解决方案的缺点是这不灵活(例如,如果您添加一个新字段,您也必须更新该String()方法),而且您还必须为struct您希望它工作的每种类型都这样做(并且您不能定义方法)对于其他包中定义的类型)。


完全灵活的解决方案可以使用反射。您可以获取字段的名称,按名称对其进行排序,然后遍历排序后的名称并获取字段值(按名称)。


该解决方案的优点是它适用于 any struct,并且即使您在结构中添加或删除字段,它也可以继续工作而无需修改。它也适用于任何类型的字段,而不仅仅是int字段。


这是一个如何做到的示例(在Go Playground上尝试):


func printFields(st interface{}) string {

    t := reflect.TypeOf(st)


    names := make([]string, t.NumField())

    for i := range names {

        names[i] = t.Field(i).Name

    }

    sort.Strings(names)


    v := reflect.ValueOf(st)

    buf := &bytes.Buffer{}

    buf.WriteString("{")

    for i, name := range names {

        val := v.FieldByName(name)

        if !val.CanInterface() {

            continue

        }

        if i > 0 {

            buf.WriteString(" ")

        }

        fmt.Fprintf(buf, "%v", val.Interface())

    }

    buf.WriteString("}")


    return buf.String()

}


查看完整回答
反对 回复 2021-10-18
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

T执行斯金格接口(见包装FMT),并请执行打印一份天体B中。

顺便提一句。这是一个愚蠢的想法。


查看完整回答
反对 回复 2021-10-18
  • 2 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信