Go - 反射

反射的概念

  • 正常情况下,代码写完,通过编译器编译成机器代码后,运行的过程就已经确定了,就像你已经编好了剧本,一旦你把剧本交到台上,演员就会按照剧本来表演,此时你再也无法干剧情的发展。

  • 对应于反射,我们大部分使用正射场景。在正射场景中,一个结构体的创建和结构体内的具体字段名称,都是确定的,一旦编译了以后就无法更改。但是在反射中,可以动态的创建结构体和在结构体中增添字段。

  • go 语言中,反射核心使用只有两个方法

    • oType := reflect.TypeOf(object)
    • oValue := reflect.ValueOf(object)
  • 反射作用,获取对象信息,获取对象属性值,调用对象的方法。

go语言调用的简单实例

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

func (p Person) SayHellow() {
	fmt.Println("hellow")
}

func main() {
	p := Person{
		Name: "张三",
		Age:  18,
	}
	typeAPI(p)
	valueAPI(p)
}
func typeAPI(obj interface{}) {
	OType := reflect.TypeOf(obj)
	oKind := OType.Kind()
	fmt.Println("oType", OType)
	fmt.Println("oKind", oKind)
	fmt.Println("oTypeName", OType.Name())

	//获取属性和方法的个数
	fmt.Println("属性的个数", OType.NumField())
	fmt.Println("方法的个数", OType.NumMethod())

	//遍历所有的属性
	for i := 0; i < OType.NumField(); i++ {
		structField := OType.Field(i)
		fmt.Println("第", i, "个属性的名称和内容", structField.Name, structField.Type)
	}

	//遍历所有的方法
	for i := 0; i < OType.NumMethod(); i++ {
		method := OType.Method(i)
		fmt.Println("第", i, "方法的属性和名称", method.Type, method.Name)
	}
}

func valueAPI(obj interface{}) {
	oValue := reflect.ValueOf(obj)
	fmt.Println("ovalue", oValue)
	fmt.Println("kind原始数据", oValue.Kind())

	// 查看 p 的所有的属性值
	for i := 0; i < oValue.NumField(); i++ {
		fmt.Println("第", i, "个属性的属性值", oValue.Field(i).Interface()) //打印属性的正射形式
	}
}

go语言反射的功能

在拿到一个结构体时,即不知道对方是啥,也不知道对象有什么方法,当时我依旧可以操作你,这就是反射的强大之处。

参考文献

https://www.bilibili.com/video/BV1Z4411J7sZ?p=3&share_source=copy_web

posted @ 2022-05-07 15:20  沧海一声笑rush  阅读(330)  评论(0编辑  收藏  举报