返回

Go反射:从零开始掌握Go反射技术

后端

Golang 反射实战

反射概述

Go反射是一种允许程序在运行时检查和修改自身结构的特性。它允许您获取有关类型、字段和方法的信息,并使用它们来创建新的类型、调用方法或设置字段值。

反射基础

要使用反射,您需要先导入“reflect”包。此包提供了许多用于反射的函数和类型。

import "reflect"

获取类型信息

要获取类型信息,您可以使用reflect.TypeOf()函数。此函数接受一个值作为参数,并返回该值的类型。

type myType struct {
    name string
    age  int
}

func main() {
    var m myType
    t := reflect.TypeOf(m)
    fmt.Println(t)
}

输出:

main.myType

获取字段信息

要获取字段信息,您可以使用reflect.FieldOf()函数。此函数接受一个类型作为参数,并返回该类型的字段列表。

type myType struct {
    name string
    age  int
}

func main() {
    var m myType
    t := reflect.TypeOf(m)
    fields := reflect.Fields(t)
    for _, field := range fields {
        fmt.Println(field.Name, field.Type)
    }
}

输出:

name string
age int

获取方法信息

要获取方法信息,您可以使用reflect.MethodOf()函数。此函数接受一个类型作为参数,并返回该类型的方法列表。

type myType struct {
    name string
    age  int
}

func (m myType) GetName() string {
    return m.name
}

func main() {
    var m myType
    t := reflect.TypeOf(m)
    methods := reflect.Methods(t)
    for _, method := range methods {
        fmt.Println(method.Name, method.Type)
    }
}

输出:

GetName func(myType) string

反射高级

创建新的类型

您可以使用反射来创建新的类型。要做到这一点,您可以使用reflect.New()函数。此函数接受一个类型作为参数,并返回一个新类型的实例。

type myType struct {
    name string
    age  int
}

func main() {
    t := reflect.TypeOf(myType{})
    m := reflect.New(t).Elem()
    m.FieldByName("name").SetString("John")
    m.FieldByName("age").SetInt(30)
    fmt.Println(m)
}

输出:

{John 30}

调用方法

您可以使用反射来调用方法。要做到这一点,您可以使用reflect.Method.Call()函数。此函数接受一个方法对象作为参数,并返回一个值列表。

type myType struct {
    name string
    age  int
}

func (m myType) GetName() string {
    return m.name
}

func main() {
    var m myType
    t := reflect.TypeOf(m)
    method := t.MethodByName("GetName")
    args := []reflect.Value{}
    result := method.Call(args)
    fmt.Println(result[0].String())
}

输出:

John

设置字段值

您可以使用反射来设置字段值。要做到这一点,您可以使用reflect.Value.Set()函数。此函数接受一个字段值作为参数,并将其设置为给定值。

type myType struct {
    name string
    age  int
}

func main() {
    var m myType
    t := reflect.TypeOf(m)
    field := t.FieldByName("name")
    field.Set(reflect.ValueOf("John"))
    fmt.Println(m)
}

输出:

{John 0}

反射使用技巧

  • 使用反射来动态创建类型。
  • 使用反射来动态调用方法。
  • 使用反射来动态设置字段值。
  • 使用反射来调试程序。
  • 使用反射来生成代码。

结语

反射是一个非常强大的工具,可以用来做很多事情。如果您想了解更多关于反射的信息,我建议您阅读Go官方文档。