当前位置:首页 / 编程技术 / 后端技术 / go语言通过反射创建结构体、赋值、并调用对应的操作
go语言通过反射创建结构体、赋值、并调用对应的操作
发布时间:2022/07/10来源:编程网

我就废话不多说了,大家还是直接看代码吧~

package main
import (
"fmt"
"reflect"
"testing"
)
type Call struct {
Num1 int
Num2 int
}
func (call Call) GetSub(name string){
fmt.Printf("%v 完成了减法运算,%v - %v = %v \n", name, call.Num1, call.Num2, call.Num1 - call.Num2)
}
func (call *Call) GetSum(name string){
fmt.Printf("%v 完成了加法运算,%v + %v = %v \n", name, call.Num1, call.Num2, call.Num1 + call.Num2)
}
func TestReflect(t *testing.T) {
var (
call *Call
rValues []reflect.Value
rValues2 []reflect.Value
)
ptrType := reflect.TypeOf(call) //获取call的指针的reflect.Type
trueType := ptrType.Elem() //获取type的真实类型
ptrValue := reflect.New(trueType) //返回对象的指针对应的reflect.Value
call = ptrValue.Interface().(*Call)
trueValue := ptrValue.Elem() //获取真实的结构体类型
trueValue.FieldByName("Num1").SetInt(123)//设置对象属性,注意这个一定要是真实的结构类型的reflect.Value才能调用,指针类型reflect.Value的会报错
//ptrValue.FieldByName("Num2").SetInt(23)
trueValue.FieldByName("Num2").SetInt(23)
//rValues = make([]reflect.Value, 0)
rValues = append(rValues, reflect.ValueOf("xiaopeng"))//调用对应的方法
fmt.Println(rValues)
trueValue.MethodByName("GetSub").Call(rValues)

//ptrValue.MethodByName("GetSub").Call(rValues)
//trueValue.MethodByName("GetSum").Call(append(rValues2, reflect.ValueOf("hiram")))
ptrValue.MethodByName("GetSum").Call(append(rValues2, reflect.ValueOf("hiram")))
fmt.Println(call)

call.GetSub("aaa")
(*call).GetSub("bbb")
call.GetSum("ccc")
(*call).GetSum("ddd")
}

补充:golang 反射 reflect 设置 struct 字段

说明1 reflect.Value区分CanSet和Can not Set

所以, 必须要返回成Can set的reflect.Value

如:


s := reflect.ValueOf(&t).Elem()

然后就可以happy的设值了, 可是不能随便设值的, 一个通用的方法就是使用Set(v Value)方法,

说明2 将值转成reflect.Value类型

下面的这段代码就是转成Value类型


sliceValue := reflect.ValueOf([]int{1, 2, 3}) // 这里将slice转成reflect.Value类型
说明3 reflect.ValueOf 参数必须是一个 指针 或 interface Elem()才可以正常调用

func (Value) Elem func (v Value) Elem() Value

Elem returns the value that the interface v contains or that the pointer v points to. It panics if v's Kind is not Interface or Ptr. It returns the zero Value if v is nil.

Elem返回接口v包含的值或指针v指向的值。 如果v的Kind不是Interface或Ptr,它会感到恐慌。 如果v为零,它将返回零值。

实例代码

代码1:


func Destroy(subj interface{}) {
stype := reflect.ValueOf(subj).Elem()
field := stype.FieldByName("Status")
if field.IsValid() {
field.SetString("Destroyed")
}
} 
func TestDestroy(t *testing.T) {
// Initialize data
jaeger := Jaeger{Name: "Cherno Alpha", Country: "RU", Status: "Active"}
kaiju := Kaiju{Alias: "Scissure", Origin: "Sydney", Status: "Unknown"}
shatterdome := Shatterdome{Location: "Lima"}
// Destroy everything
Destroy(&jaeger)
Destroy(&kaiju)
Destroy(&shatterdome)
// Check the result
if jaeger.Status != "Destroy" {
t.Error("jaeger was not destroyed")
}
if kaiju.Status != "Destroy" {
t.Error("kaiju was not destroyed")
}
}

代码2:


type T struct {
    Age int
    Name string
    Children []int
}
t := T{12, "someone-life", nil}
s := reflect.ValueOf(&t).Elem()
s.Field(0).SetInt(123) // 内置常用类型的设值方法
sliceValue := reflect.ValueOf([]int{1, 2, 3}) // 这里将slice转成reflect.Value类型
s.FieldByName("Children").Set(sliceValue)
 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。如有错误或未考虑完全的地方,望不吝赐教。


分享到:
免责声明:本文仅代表文章作者的个人观点,与本站无关,请读者仅作参考,并自行核实相关内容。文章内容来源于网络,版权归原作者所有,如有侵权请与我们联系,我们将及时删除。
资讯推荐
热门最新
精品工具
全部评论(0)
剩余输入数量90/90
暂无任何评论,欢迎留下你的想法
你可能感兴趣的资讯
换一批