从一组结构中记录单个字段的最简单方法是什么?

假设我有一个功能,可以吸收一部分 Person:

type Person struct {
    ID              uuid.UUID   
    FirstName       string
    LastName        string
    ... plus 20 more fields
}

在记录时,我可能只想记录ID。有没有一种简单的方法可以在不创建其他类型的情况下执行此操作?我正在使用 Logrus。如果我在JS中,我会只使用map函数。示例记录器行:

logger.Debugf("personProcessor starting for people: %v", persons)

但这将导致我的日志中出现大量不必要的输出。ID足以找到我们正在处理的人。


婷婷同学_
浏览 92回答 3
3回答

泛舟湖上清波郎朗

使用反射包编写用于提取字段的“通用”函数:func extractField(s interface{}, name string) []interface{} {&nbsp; &nbsp; var result []interface{}&nbsp; &nbsp; v := reflect.ValueOf(s)&nbsp; &nbsp; for i := 0; i < v.Len(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; result = append(result, reflect.Indirect(v.Index(i)).FieldByName(name).Interface())&nbsp; &nbsp; }&nbsp; &nbsp; return result}像这样使用它:logger.Debugf("personProcessor starting for people: %v", extractField(persons, "ID"))该功能可以扩展到包括格式化花里胡哨的东西:// sprintFields prints the field name in slice of struct s&nbsp;// using the specified format.func sprintFields(s interface{}, name string, sep string, format string) string {&nbsp; &nbsp; var fields []string&nbsp; &nbsp; v := reflect.ValueOf(s)&nbsp; &nbsp; for i := 0; i < v.Len(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; fields = append(fields,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Sprintf(format,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reflect.Indirect(v.Index(i)).FieldByName(name).Interface()))&nbsp; &nbsp; }&nbsp; &nbsp; return strings.Join(fields, sep)}

守候你守候我

请参阅此使用反射和字符串构建的函数:func printPersonField(persons []Person, field string) {&nbsp; &nbsp; buf := bytes.NewBuffer(nil)&nbsp; &nbsp; fmt.Fprintf(buf, "Persons (%s): [", field)&nbsp; &nbsp; for i := range persons {&nbsp; &nbsp; &nbsp; &nbsp; if i > 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprint(buf, ", ")&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprint(buf, reflect.ValueOf(persons[i]).FieldByName(field).Interface())&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Fprint(buf, "]")&nbsp; &nbsp; log.Println(buf.String())}用法如下:func main() {&nbsp; &nbsp; persons := []Person{&nbsp; &nbsp; &nbsp; &nbsp; {1, "first1", "last1"},&nbsp; &nbsp; &nbsp; &nbsp; {2, "first2", "last2"},&nbsp; &nbsp; &nbsp; &nbsp; {3, "first3", "last3"},&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; printPersonField(persons, "ID")&nbsp; &nbsp; printPersonField(persons, "FirstName")&nbsp; &nbsp; printPersonField(persons, "LastName")&nbsp; &nbsp;&nbsp;}输出:2009/11/10 23:00:00 Persons (ID): [1, 2, 3]2009/11/10 23:00:00 Persons (FirstName): [first1, first2, first3]2009/11/10 23:00:00 Persons (LastName): [last1, last2, last3]请注意,这不是“通用”,因为它不适用于任何类型。它严格接受输入。如果你想让它适用于其他类型的其他结构切片,那么请参阅我爱反射的答案。[]Person

FFIVE

我不确定 Logrus,但这适用于标准库:package mainimport (&nbsp; &nbsp;"fmt"&nbsp; &nbsp;"strconv")type Person struct {&nbsp; &nbsp;ID int&nbsp; &nbsp;FirstName, LastName string}func (p Person) String() string {&nbsp; &nbsp;return strconv.Itoa(p.ID)}func main() {&nbsp; &nbsp;p := Person{9, "First", "Last"}&nbsp; &nbsp;fmt.Println(p) // 9}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go