当前位置: 首页 > news >正文

GoLang 反射

文章目录

    • 讲讲Golang的反射
    • 示例
      • 动态类型判断与转换
      • 结构体字段操作(打印)
      • 接口调用

讲讲Golang的反射

反射是一种在运行时动态操作对象、获取类型信息、调用方法等的能力。

在Golang中,反射是通过reflect包来实现的。反射允许程序在运行时获取任意类型的对象的类型信息和值,并对其进行操作。以下是Golang反射的一些关键点:

  • 获取类型和值:使用reflect.TypeOf()获取对象的类型,reflect.ValueOf()获取对象的值。
  • 修改反射对象的值:反射对象的值是原值的拷贝,要修改原值需要传入变量的地址,并使用Elem()方法获取指针指向的值,然后通过Set()方法修改。
  • 动态调用方法:可以通过reflect.Value的MethodByName()方法获取方法,然后使用Call()方法调用该方法。
  • 遍历结构体字段和方法:反射可以获取结构体的字段和方法信息,包括字段的名称、类型、标签等。
  • 性能影响:反射的使用会带来一定的性能开销,因为它在运行时动态解析类型和值。

示例

而Golang通过reflect.Value直接获取对象的方法并调用

动态类型判断与转换

通过反射判断字段类型,这种情况比较常见。

package main

import (
	"fmt"
	"reflect"
)

func printTypeAndValue(v interface{}) {
	value := reflect.ValueOf(v)
	typ := value.Type()
	fmt.Printf("Type: %s, Value: %v\n", typ.Name(), value.Interface())
}

func main() {
	var num int = 42
	var str string = "hello"
	var floatNum float64 = 3.14

	printTypeAndValue(num)    // Type: int, Value: 42
	printTypeAndValue(str)    // Type: string, Value: hello
	printTypeAndValue(floatNum) // Type: float64, Value: 3.14
}

结构体字段操作(打印)

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

func printStructFields(v interface{}) {
	val := reflect.ValueOf(v)
	typ := val.Type()

	for i := 0; i < val.NumField(); i++ {
		fieldName := typ.Field(i).Name
		fieldValue := val.Field(i).Interface()
		fmt.Printf("%s: %v\n", fieldName, fieldValue)
	}
}

func main() {
	p := Person{Name: "Alice", Age: 30}
	printStructFields(p)
	// 输出:
	// Name: Alice
	// Age: 30
}

接口调用

package main

import (
	"fmt"
	"reflect"
)

type Greeter interface {
	Greet() string
}

type EnglishGreeter struct{}

func (e EnglishGreeter) Greet() string {
	return "Hello"
}

func callGreet(g Greeter) {
	val := reflect.ValueOf(g)
	method := val.MethodByName("Greet")
	if method.IsValid() {
		result := method.Call(nil)
		fmt.Println(result[0].Interface()) // 输出:Hello
	}
}

func main() {
	greeter := EnglishGreeter{}
	callGreet(greeter)
}

相关文章:

  • pppd拨号模块的总结【Linux】
  • 【从零开始学习计算机科学与技术】计算机网络(五)网络层
  • 【npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree】
  • 3.4 二分查找专题:LeetCode 69. x 的平方根
  • TCP、UDP协议的应用、ServerSocket和Socket、DatagramSocket和DatagramPacket
  • 查询修改ORACLE的server、客户端和导出dmp文件 字符集编码
  • SpringBoot-2整合MyBatis以及基本的使用方法
  • 大模型学习-让其他电脑可访问本地ollama的模型并进行流式响应
  • AMD锐龙8845HS+780M核显 虚拟机安装macOS 15 Sequoia 15.0.1 (2024.10)
  • 【ELK】节省存储 之 压缩存储方式调整
  • element-ui image 组件源码分享
  • cls(**dict(data, id=id))灵活地从一个字典生成实例,同时确保某些关键字段(如 id)被正确设置或覆盖
  • 问deepseek: 如何用CUDA实现PBiCGSTAB稀疏矩阵迭代算法,写段示例代码
  • OLE注册是什么?
  • 博客图床 VsCode + PicGo + 阿里云OSS
  • $.ajax的contentType设置及对应后端数据获取方式
  • ViT、DETR 和 Swin Transformer :基于 Transformer 的计算机视觉(CV)模型
  • vmware tools灰化
  • Unity打包的WebGL包打不开问题解决方案,以及WebGL包嵌入至Vue2中的步骤
  • QT程序双击可执行文件运行方法
  • 中国防疫队深入缅甸安置点开展灾后卫生防疫工作
  • 湖南华容县通报“大垱湖水质受污染”,爆料者:现场已在灌清水
  • 海南儋州市委副书记任延新已赴市人大常委会履新
  • 上海数学教育及数学科普专家陈永明去世,享年85岁
  • 澎湃思想周报丨数字时代的育儿;凛冬已至好莱坞
  • 党旗下的青春|83岁仍在“下生活”,他说生活是创作的源泉