Go语言反射深入讲解

反射基础概念什么是反射?反射是一种在运行时检查和操作类型的机制。它允许程序动态地获取类型信息,并对对象进行操作。基本类型反射的基本类型包括:reflect.Type:表示类型信息。reflect.Value:表示值信息。获取类型信息使用reflect.TypeOfpackag

反射基础概念

什么是反射?
反射是一种在运行时检查和操作类型的机制。它允许程序动态地获取类型信息,并对对象进行操作。

基本类型
反射的基本类型包括:

  • reflect.Type:表示类型信息。
  • reflect.Value:表示值信息。

获取类型信息

使用 reflect.TypeOf

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var a int = 10
	t := reflect.TypeOf(a)
	fmt.Println(t) // 输出:int
}

使用 reflect.ValueOf

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var a int = 10
	v := reflect.ValueOf(a)
	fmt.Println(v) // 输出:10
}

类型转换

使用 Interface 方法

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var a int = 10
	v := reflect.ValueOf(a)
	b := v.Interface().(int)
	fmt.Println(b) // 输出:10
}

使用 Convert 方法

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var a int = 10
	v := reflect.ValueOf(a)
	b := v.Convert(reflect.TypeOf(float64(0))).Interface().(float64)
	fmt.Println(b) // 输出:10
}

检查类型

使用 Kind 方法

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var a int = 10
	t := reflect.TypeOf(a)
	fmt.Println(t.Kind()) // 输出:int
}

使用 Type 方法

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

func main() {
	p := Person{"Alice", 25}
	t := reflect.TypeOf(p)
	fmt.Println(t) // 输出:main.Person
}

操作结构体

获取结构体字段

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

func main() {
	p := Person{"Alice", 25}
	v := reflect.ValueOf(p)
	t := v.Type()

	for i := 0; i < v.NumField(); i++ {
		field := t.Field(i)
		value := v.Field(i)
		fmt.Printf("%s: %v\n", field.Name, value.Interface())
	}
}

修改结构体字段

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

func main() {
	p := Person{"Alice", 25}
	v := reflect.ValueOf(&p).Elem()
	t := v.Type()

	for i := 0; i < v.NumField(); i++ {
		field := t.Field(i)
		value := v.Field(i)
		switch field.Name {
		case "Name":
			value.SetString("Bob")
		case "Age":
			value.SetInt(30)
		}
	}

	fmt.Println(p) // 输出:{Bob 30}
}

操作数组和切片

获取数组和切片长度

package main

import (
	"fmt"
	"reflect"
)

func main() {
	a := []int{1, 2, 3, 4, 5}
	v := reflect.ValueOf(a)
	fmt.Println(v.Len()) // 输出:5
}

遍历数组和切片

package main

import (
	"fmt"
	"reflect"
)

func main() {
	a := []int{1, 2, 3, 4, 5}
	v := reflect.ValueOf(a)

	for i := 0; i < v.Len(); i++ {
		fmt.Println(v.Index(i).Interface())
	}
}

操作映射表

获取映射表键值

package main

import (
	"fmt"
	"reflect"
)

func main() {
	m := map[string]int{"a": 1, "b": 2, "c": 3}
	v := reflect.ValueOf(m)

	for _, key := range v.MapKeys() {
		value := v.MapIndex(key)
		fmt.Printf("%v: %v\n", key.Interface(), value.Interface())
	}
}

修改映射表

package main

import (
	"fmt"
	"reflect"
)

func main() {
	m := map[string]int{"a": 1, "b": 2, "c": 3}
	v := reflect.ValueOf(&m).Elem()

	v.SetMapIndex(reflect.ValueOf("d"), reflect.ValueOf(4))

	fmt.Println(m) // 输出:map[a:1 b:2 c:3 d:4]
}

操作接口

获取接口值

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var i interface{} = "Hello, World!"
	v := reflect.ValueOf(i)
	fmt.Println(v.Interface()) // 输出:Hello, World!
}

修改接口值

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var i interface{} = "Hello, World!"
	v := reflect.ValueOf(&i).Elem()
	v.Set(reflect.ValueOf("Goodbye, World!"))

	fmt.Println(i) // 输出:Goodbye, World!
}

操作函数

调用函数

package main

import (
	"fmt"
	"reflect"
)

func add(a, b int) int {
	return a + b
}

func main() {
	args := []reflect.Value{reflect.ValueOf(1), reflect.ValueOf(2)}
	result := reflect.ValueOf(add).Call(args)[0].Interface().(int)
	fmt.Println(result) // 输出:3
}

调用方法

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name string
	Age  int
}

func (p *Person) SayHello() string {
	return fmt.Sprintf("%s says hello!", p.Name)
}

func main() {
	p := &Person{"Alice", 25}
	method := reflect.ValueOf(p).MethodByName("SayHello")
	result := method.Call(nil)[0].Interface().(string)
	fmt.Println(result) // 输出:Alice says hello!
}

反射与类型断言

类型断言

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var i interface{} = "Hello, World!"
	if str, ok := i.(string); ok {
		fmt.Println(str) // 输出:Hello, World!
	} else {
		fmt.Println("Not a string")
	}
}

使用反射进行类型断言

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var i interface{} = "Hello, World!"
	v := reflect.ValueOf(i)
	if v.Kind() == reflect.String {
		fmt.Println(v.Interface()) // 输出:Hello, World!
	} else {
		fmt.Println("Not a string")
	}
}

反射与类型转换

类型转换

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var i interface{} = 10
	v := reflect.ValueOf(i)
	f := v.Convert(reflect.TypeOf(float64(0))).Interface().(float64)
	fmt.Println(f) // 输出:10
}

复杂类型的转换

package main

import (
	"fmt"
	"reflect"
)

type Point struct {
	X float64
	Y float64
}

func main() {
	var p interface{} = Point{X: 1.0, Y: 2.0}
	v := reflect.ValueOf(p)
	newPoint := v.Convert(reflect.TypeOf(Point{})).Interface().(Point)
	fmt.Println(newPoint) // 输出:{1 2}
}
点赞 0
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论