后彼 发表于 2025-8-5 22:43:38

Golang基础笔记十六之反射

本文首发于公众号:Hunter后端
原文链接:Golang基础笔记十六之反射
反射可以用于程序在运行时检查、修改自身类型和值,主要通过 reflect 包实现。
首先,我们提出一个需求,要打印出一个结构体 struct 的各个字段及其对应的标签数据,按照当前的笔记内容是无法解决该问题的,但是我们可以使用反射操作来完成。
以下是本篇笔记目录:

[*]变量的类型和值
[*]修改变量的值
[*]遍历结构体字段
[*]动态调用函数
1、变量的类型和值

先引入 reflect 模块:
import (
    "reflect"
)我们可以通过 reflect.TypeOf() 获取变量的类型:
var x float64 = 3.5

t := reflect.TypeOf(x)返回的 t 是 Type接口,我们可以进一步调用 t 的方法来获取类型信息:
// 变量的类型名称:
fmt.Println("x 的类型名称是: ", t.Name())

// 判断类型的类别:
fmt.Println("x 的类型是否是 float64: ", t.Kind() == reflect.Float64)获取变量的值信息:
v := reflect.ValueOf(x)
fmt.Println("value: ", v.Float() == 3.5)2、修改变量的值

如果要修改这个变量的值,我们需要用到指针,以下是操作示例:
var x float64 = 3.5

// 这里获取的是变量的地址的值,如果直接 reflect.ValueOf(x) 获取的是 x 的副本
p := reflect.ValueOf(&x)

// Elem() 方法获取指针指向的实际值,是解引用的操作
v := p.Elem()

// 重新赋值的操作
v.SetFloat(4.9)
fmt.Println("new value: ", x)3、遍历结构体字段

我们先定义一个结构体如下:
type Person struct {
        Id   int    `json:"id" form:"id"`
        Name string `json:"name"`
}打印一个 Person 示例各个字段的名称及其值的操作如下:
p := Person{
    Id:   1,
    Name: "hunter",
}
t := reflect.TypeOf(p)
v := reflect.ValueOf(p)

for i := 0; i < t.NumField(); i++ {
    field := t.Field(i)
    value := v.Field(i)

    fmt.Printf("field_name:%s, field_type:%s, value:%v\n", field.Name, field.Type, value.Interface())
}在这里,我们通过 t.NumField() 方法获取到 p 的字段个数,并使用 t.Field(i) 和 v.Field(i) 获取到对应字段类型和值。
接着对于每个 field 和 value,我们可以打印出对应的字段名称,字段类型和值。
我们还可以使用 field.Tag.Get() 的方式获取到字段标签的值:
fmt.Printf("json_tag:%s, form_tag:%s\n", field.Tag.Get("json"), field.Tag.Get("form"))如果后续我们介绍 Golang 的 validator 模块,可以了解到,validator 就是通过 struct 定义的标签使用反射来对字段值进行验证的。
4、动态调用函数

我们还可以使用反射来动态调用函数,比如某个函数如下:
func Add(a, b int) int {
    return a + b
}使用反射动态调用的操作如下:
func main() {
    targetFunc := reflect.ValueOf(Add)

    args := []reflect.Value{reflect.ValueOf(2), reflect.ValueOf(5)}

    result := targetFunc.Call(args)
    fmt.Println("动态调用 Add 函数,result: ", result.Int())
}注意:虽然反射可以为我们提供一些便利的操作,但是代码的可读性和可维护性会降低,且会降低性能,需要在实际生产中谨慎使用。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

髭赌 发表于 2025-12-5 10:12:02

谢谢分享,试用一下

求几少 发表于 2025-12-13 06:10:14

谢谢楼主提供!

黎瑞芝 发表于 2025-12-17 04:04:06

分享、互助 让互联网精神温暖你我

里豳朝 发表于 2026-1-11 11:25:11

不错,里面软件多更新就更好了

裆趾针 发表于 2026-1-13 14:52:06

过来提前占个楼

表弊捞 发表于 2026-1-13 21:38:38

感谢发布原创作品,程序园因你更精彩

齐娅晶 发表于 2026-1-17 09:32:11

东西不错很实用谢谢分享

空娅芬 发表于 2026-1-17 21:36:45

前排留名,哈哈哈

兑谓 发表于 2026-1-20 00:01:24

喜欢鼓捣这些软件,现在用得少,谢谢分享!

怃膝镁 发表于 2026-1-20 19:14:03

不错,里面软件多更新就更好了

归筠溪 发表于 2026-1-21 16:49:27

喜欢鼓捣这些软件,现在用得少,谢谢分享!

上官泰 发表于 2026-1-24 12:02:27

感谢发布原创作品,程序园因你更精彩

煞赶峙 发表于 2026-1-25 08:17:53

喜欢鼓捣这些软件,现在用得少,谢谢分享!

奚娅琼 发表于 2026-2-1 04:06:35

这个好,看起来很实用

遇玷 发表于 2026-2-2 03:47:41

感谢分享

崔竹 发表于 2026-2-2 03:47:47

东西不错很实用谢谢分享

剩鹄逅 发表于 2026-2-2 16:24:00

东西不错很实用谢谢分享

阴昭昭 发表于 2026-2-7 14:38:50

用心讨论,共获提升!

篙菠 发表于 2026-2-8 10:06:31

谢谢楼主提供!
页: [1] 2 3
查看完整版本: Golang基础笔记十六之反射