golang reflect 常見示例

zongzw發表於2024-05-30

reflect是golang中超程式設計的能力體現。

需要注意的是,reflect儘量不用,有效能問題,也有避免濫用的考慮。

package main

import (
	"log"
	"reflect"
)

type A struct {
	a int
	b string
	c bool
}

// 實驗reflect的相關函式
func main() {
	typeValue()
	callFunc()
}

func others() {
	// 型別賦值
	// newTValue.Elem().FieldByName(newTTag).Set(tValue)

	// 依據 kind 分支
	// reflect.TypeOf(a).Kind()
	// case reflect.Int:
	// case reflect.String:
}

// 動態呼叫函式
func callFunc() {
	o := &A{}

	in := []reflect.Value{reflect.ValueOf(1), reflect.ValueOf("xyz"), reflect.ValueOf(true)}
	done := reflect.ValueOf(o).MethodByName("Create").Call(in)
	// 型別斷言: done[0].Interface().(bool)
	log.Printf("called Created and returned: %v obj: %v", done[0].Interface().(bool), o)
}
func (o *A) Create(a int, b string, c bool) bool {
	o.a = a
	o.b = b
	o.c = c
	return true
}

// 使用reflect實現物件及成員的型別與數值獲取
func typeValue() {
	// 宣告一個結構體物件
	x := A{a: 1, b: "xyz", c: true}

	// 獲取結構體的型別
	log.Printf("type of x: %T", x)
	log.Printf("type of x: %s", reflect.TypeOf(x))
	log.Printf("type of x: %s", reflect.TypeOf(x).String())

	// 獲取結構體物件的值
	log.Printf("value of x: %v", x)
	log.Printf("value of x: %v", reflect.ValueOf(x))
	log.Printf("value of x: %v", reflect.ValueOf(x).String())

	// 獲取結構體成員的型別和值
	log.Printf("elem num of x: %d", reflect.TypeOf(x).NumField())
	log.Printf("elem num of x: %d", reflect.ValueOf(x).NumField())
	log.Printf("x elem 0: name: %s type: %s, value: %v",
		reflect.TypeOf(x).Field(0).Name,
		reflect.TypeOf(x).Field(0).Type,
		reflect.ValueOf(x).Field(0))

	// 獲取結構體成員的型別和值
	log.Printf("x elem 1: name: %s type: %s, value: %v",
		reflect.TypeOf(x).Field(1).Name,
		reflect.ValueOf(x).Field(1).Type(),
		reflect.ValueOf(x).Field(1))
}

參考repo: https://github.com/zongzw-learn/learn-go/blob/master/syntax/reflect/main.go

相關文章