golang SDK: reflect 反射机制

50 阅读1分钟

获取对象指针指向的对象

这个例子中获取对象指针所指向的真正类型对象。

package main

import (
	"fmt"
	"reflect"
)

type Hello struct {
	A int
	Message
	C []int
}
type Message struct {
	Content string
}
func (h Message) printMsg() string{

	return fmt.Sprint("msg")
}

// indirectArbitraryPointer returns *ptrToObject for an arbitrary pointer
func indirectArbitraryPointer(ptrToObject interface{}) interface{} {
	return reflect.Indirect(reflect.ValueOf(ptrToObject)).Interface()
}
func main() {

	registries:=&Hello{
		A: 1,
		C: []int{1,2,3},
	}
	back:=indirectArbitraryPointer(registries) // Hello类型的变量

	if backOrigin,ok:= back.(Hello);ok{ // 强制类型转换
		backOrigin.A=2
		backOrigin.C[0]=5
		fmt.Println(backOrigin)
	}

	fmt.Println(registries)
}

检测struct是否实现interface

package main

import (
	"fmt"
	"reflect"
)

type Hello interface {
	SayHello() string
}

type hello struct {
	name string
}

func (h hello) SayHello() string {
	return fmt.Sprintf("hello %s :)",h.name)
}
// CheckImplements check whether obj pointed by implPointer implements the obj pointed by ifacePointer
func CheckImplements(ifacePointer interface{},implPointer interface{}){
	iface:=reflect.TypeOf(ifacePointer).Elem()
	impl:=reflect.TypeOf(implPointer)

	if impl.Implements(iface){
		fmt.Println(fmt.Sprintf("%s implements %s",impl,iface))
	}
}

func main() {
	// a *Hello type pointer whose value is nil
	H:=(*Hello)(nil)
	// a *hello type pointer whose value is nil
	h:=(*hello)(nil)

	CheckImplements(H,h) // => *main.hello implements main.Hello
}

获取集合元素的类型

如何获取集合类(map,array,slice etc.)的子元素类型

package main

import (
	"fmt"
	"reflect"
)

func main() {

	list := &[]string{"h"}
	// *[]string deference to []string
	listv := reflect.ValueOf(list).Elem()

	// get the element type of slice
	typev:=listv.Type().Elem()
	
	fmt.Println(listv.Type()) // => []string
	fmt.Println(typev)  // => string
}

获取结构体的值

package main

import (
	"fmt"
	"reflect"
)

type Message struct {
	Content string
}
func main() {
	message:=&Message{
		Content: "hello world",
	}
	v:=reflect.ValueOf(*message).FieldByName("Content").Interface()
	fmt.Println(v) // => hello world
}