Go语言如何将结构体字段作为参数传入函数获取对应返回值
解决方案
Go语言没有直接传递结构体字段引用的语法,你可以通过以下3种常用方式实现需求,按需选择即可:
方案1:传入字段选择标记(普通场景首选)
通过新增参数标记要选择的字段,性能无损耗,逻辑清晰易维护,适合字段数量固定的场景:
package main import "fmt" type s struct { a int b int } // 定义字段选择常量,避免硬编码魔法值 const ( FieldA = iota FieldB ) // 新增field参数指定要返回的字段 func c(s s, field int) int { var t int switch field { case FieldA: t = s.a case FieldB: t = s.b default: panic("非法的字段选择参数") } return t } func main() { obj := s{5, 8} fmt.Println(c(obj, FieldA)) // 输出5 fmt.Println(c(obj, FieldB)) // 输出8 }
方案2:传入字段提取函数(灵活度高)
将字段提取逻辑作为函数参数传入,后续新增结构体字段不需要修改c函数的实现,适合字段多、提取逻辑可能变化的场景:
package main import "fmt" type s struct { a int b int } // 第二个参数接收字段提取函数 func c(s s, getter func(s) int) int { return getter(s) } func main() { obj := s{5, 8} // 传参时直接指定要提取的字段即可 fmt.Println(c(obj, func(s s) int { return s.a })) // 输出5 fmt.Println(c(obj, func(s s) int { return s.b })) // 输出8 }
方案3:反射实现(仅适用动态字段场景)
如果字段名是运行时动态确定的,可以通过反射实现,注意反射要求结构体字段首字母大写公开,且性能略低,非必要不推荐使用:
package main import ( "fmt" "reflect" ) // 反射访问要求字段首字母大写公开 type s struct { A int B int } // 传入字段名即可动态取值 func c(s s, fieldName string) int { field := reflect.ValueOf(s).FieldByName(fieldName) if !field.IsValid() || field.Kind() != reflect.Int { panic("字段名不合法或字段类型不为int") } return int(field.Int()) } func main() { obj := s{A:5, B:8} fmt.Println(c(obj, "A")) // 输出5 fmt.Println(c(obj, "B")) // 输出8 }
内容的提问来源于stack exchange,提问作者user17148257
相关产品推荐
相关产品推荐

