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

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

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

Go
婷婷同学_ 2022-08-24 16:48:14
假设我有一个功能,可以吸收一部分 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足以找到我们正在处理的人。
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

使用反射包编写用于提取字段的“通用”函数:


func extractField(s interface{}, name string) []interface{} {

    var result []interface{}

    v := reflect.ValueOf(s)

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

        result = append(result, reflect.Indirect(v.Index(i)).FieldByName(name).Interface())

    }

    return result

}

像这样使用它:


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


该功能可以扩展到包括格式化花里胡哨的东西:


// sprintFields prints the field name in slice of struct s 

// using the specified format.

func sprintFields(s interface{}, name string, sep string, format string) string {

    var fields []string

    v := reflect.ValueOf(s)

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

        fields = append(fields, 

            fmt.Sprintf(format,

                reflect.Indirect(v.Index(i)).FieldByName(name).Interface()))

    }

    return strings.Join(fields, sep)

}


查看完整回答
反对 回复 2022-08-24
?
守候你守候我

TA贡献1802条经验 获得超10个赞

请参阅此使用反射和字符串构建的函数:


func printPersonField(persons []Person, field string) {

    buf := bytes.NewBuffer(nil)

    fmt.Fprintf(buf, "Persons (%s): [", field)

    for i := range persons {

        if i > 0 {

            fmt.Fprint(buf, ", ")

        }

        fmt.Fprint(buf, reflect.ValueOf(persons[i]).FieldByName(field).Interface())

    }

    fmt.Fprint(buf, "]")

    log.Println(buf.String())

}

用法如下:


func main() {

    persons := []Person{

        {1, "first1", "last1"},

        {2, "first2", "last2"},

        {3, "first3", "last3"},

    }

    

    printPersonField(persons, "ID")

    printPersonField(persons, "FirstName")

    printPersonField(persons, "LastName")

    

}

输出:


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


查看完整回答
反对 回复 2022-08-24
?
FFIVE

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

我不确定 Logrus,但这适用于标准库:


package main


import (

   "fmt"

   "strconv"

)


type Person struct {

   ID int

   FirstName, LastName string

}


func (p Person) String() string {

   return strconv.Itoa(p.ID)

}


func main() {

   p := Person{9, "First", "Last"}

   fmt.Println(p) // 9

}


查看完整回答
反对 回复 2022-08-24
  • 3 回答
  • 0 关注
  • 90 浏览
慕课专栏
更多

添加回答

举报

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