You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 16:54:05