如何按字母顺序对结构字段排序 [英] How to sort struct fields in alphabetical order

查看:119
本文介绍了如何按字母顺序对结构字段排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获取按字段排序的struct输出?

How could I get an output of struct, sorted by fields?

type T struct {
    B int
    A int
}

t := &T{B: 2, A: 1}

doSomething(t)

fmt.Println(t)  // &{1 2} --> Sorted by fields

推荐答案

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

A struct is an ordered collection of fields. The fmt package uses reflection to get the fields and values of a struct value, and generates output in the order in which they were defined.

最简单的解决方案是在已经按字母顺序排列字段的地方声明您的类型:

So the simplest solution would be to declare your type where you already have your fields arranged in alphabetical order:

type T struct {
    A int
    B int
}

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

If you can't modify the order of fields (e.g. memory layout is important), you can implement the Stringer interface by specifying a String() method for your struct type:

func (t T) String() string {
    return fmt.Sprintf("{%d %d}", t.A, t.B)
}

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

The fmt package checks if the passed value implements Stringer, and if it does, calls its String() method to generate the output.

此解决方案的缺点是它不灵活(例如,如果添加新字段,也必须更新String()方法),并且还必须为每个要使用的struct类型执行此操作工作(您不能为其他包中定义的类型定义方法).

Cons of this solution is that this is not flexible (e.g. if you add a new field, you have to update the String() method too), also you have to do it for every struct type you want it to work (and you can't define methods for types defined in other packages).

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

The completely flexible solution can use reflection. You can get the names of fields, sort them by name, and then iterate over the sorted names and get the field values (by name).

此解决方案的优点是,它适用于任何struct,即使您从结构中添加或删除字段,它也可以保持工作而无需修改.它也适用于任何类型的字段,而不仅仅是int字段.

Pros of this solution is that this works for any struct, and it keeps working without modification even if you add or remove fields from your structs. It also works for fields of any type, not just for int fields.

下面是一个示例操作方法(在转到游乐场上尝试):

Here is an example how to do it (try it on the 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()
}

这篇关于如何按字母顺序对结构字段排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆