当前位置: 首页 > news >正文

Go反射-通过反射调用结构体的方法(带入参)

使用反射前,我们需要提前做好映射配置

papckage_struct_relationship.go

package reflectcommonimport (api "template/api"
)// 包名到包对象的映射
var structMap = map[string]func() interface{}{"template/api": func() interface{} { return &api.User{} },   // 调用User结构体的方法
}

反射核心代码

package reflectcommonimport ("fmt""reflect"api "template/api"
)/*
args []interface{},支持任意类型的参数
*/
func CallPackageStructMethod(pkgPath, methodName string, args []interface{}) ([]reflect.Value, *[]error) {fmt.Println(123123)errs := []error{}// 1. 获取构造函数constructor, ok := structMap[pkgPath]if !ok {errs = append(errs, fmt.Errorf("包 %s 未注册", pkgPath))return nil, &errs}// 2. 创建实例instance := constructor()instanceValue := reflect.ValueOf(instance)// 3. 检查是否为指针if instanceValue.Kind() != reflect.Ptr {errs = append(errs, fmt.Errorf("构造函数必须返回指针"))return nil, &errs}// 4. 获取指向的结构体值structValue := instanceValue.Elem()if structValue.Kind() != reflect.Struct {errs = append(errs, fmt.Errorf("预期结构体,实际得到 %s", structValue.Kind()))return nil, &errs}// 5. 获取方法method := instanceValue.MethodByName(methodName)if !method.IsValid() {errs = append(errs, fmt.Errorf("方法 %s 不存在", methodName))return nil, &errs}// 6. 准备参数var in []reflect.Valuefor _, arg := range args {in = append(in, reflect.ValueOf(arg))}// 7. 调用方法并返回结果results := method.Call(in)return results, nil
}

定义结构体方法

template/api/create_token.go

package apiimport ("fmt""template/common""template/types"
)type User struct {UserId stringToken  string
}func newCreateTokenApiV1() *types.Api {apiV1 := types.Api{Host:        "",Prefix:      "",Version:     "/v1",Url:         "/token/create",Method:      "POST",ContentType: "application/json",}return &apiV1
}func (user User) CreateTokenApi(user1 map[string]interface{}, userId, token string) (*types.Api, *types.Result, error) {// 处理请求URLdata := map[string]interface{}{"userId": userId,"token":  token,"user":   user1,}fmt.Println("xxxxxxx---进来啦")apiV1 := newCreateTokenApiV1()apiV1.ReqData = dataresult := &types.Result{Header:   nil,Duration: 2,Resp: struct {Code      string      `json:"code"`Message   string      `json:"message"`RequestId string      `json:"requestId"`Response  interface{} `json:"response"`}{Code:      "000000",Message:   "success",RequestId: "123456",Response:  data,},}return apiV1, result, nil
}

调用

package mainimport ("template/common"reflectcommon "template/reflectCommon""template/types""github.com/douyu/jupiter/pkg/xlog"
)func main() {// 这里的顺序主要要与调用发放的入参保持一致reqData := []interface{}{map[string]interface{}{"id": 1, "name": "test", "age": 18},"MyUserid","MuToken",} }}results, errList := reflectcommon.CallPackageStructMethod("template/api", "CreateTokenApi", reqData)if errList != nil && len(*errList) > 0 {xlog.Error("CreateTokenApi failed", xlog.Any("error", errList))return}// 5. 解析返回结果 (api, result, error)if len(results) >= 3 {apiV1 := results[0].Interface().(*types.Api)result := results[1].Interface().(*types.Result)err := results[2].Interface() // 可能是nilxlog.Info("success",xlog.Any("api", apiV1),xlog.Any("result", result),xlog.Any("error", err))}}

执行日志:

PS D:\project\go\src\template> go run .
123123
xxxxxxx—进来啦
1746258031 INFO default success {“api”: {“name”:“”,“prefix”:“/efile”,“version”:“/v1”,“url”:“/token/create”,“fullUrl”:“”,“method”:“POST”,“reqHeader”:null,“ContentType”:“application/json”,“param”:null,“reqData”:{“token”:“MuToken”,“user”:{“age”:18,“id”:1,“name”:“test”},“userId”:“MyUserid”},“excuteUid”:“”,“respContentType”:“”}, “result”: {“header”:null,“duration”:2,“resp”:{“code”:“000000”,“message”:“success”,“requestId”:“123456”,“response”:{“token”:“MuToken”,“user”:{“age”:18,“id”:1,“name”:“test”},“userId”:“MyUserid”}}}, “error”: null}

http://www.xdnf.cn/news/263053.html

相关文章:

  • 解决奥壹oelove婚恋原生小程序上架问题,彻底解决解对问题增强版旗舰版通用
  • 计算机网络八股文--day4 --传输层TCP与UDP
  • WebAPI项目从Newtonsoft.Json迁移到System.Text.Json踩坑备忘
  • 【项目实践】boost 搜索引擎
  • 基于 JSP 和 Servlet 的数字信息分析小应用
  • 【Linux】驱动开发方法
  • ES6/ES11知识点 续一
  • 人工智能发展史 — 物理学诺奖之 Hopfield 联想和记忆神经网络模型
  • 19:常见的Halcon数据格式
  • 优化01-统计信息
  • 深入解析 SqlSugar 与泛型封装:实现通用数据访问层
  • 图论之幻想迷宫
  • 使用Rust + WebAssembly提升前端渲染性能:从原理到落地
  • 网络安全:sql注入练习靶场——sqli_labs安装保姆级教程
  • 【tcp连接windows redis】
  • c++_2011 NOIP 普及组 (1)
  • Python Django基于小波变换的数字水印技术实现系统【附源码、文档说明】
  • (37)VTK C++开发示例 ---纹理地球
  • 多协议 Tracker 系统架构与传感融合实战 第五章 卡尔曼滤波定位算法实战
  • Linux《进程概念(下)》
  • 【Linux】Petalinux驱动开发基础
  • 物联网智能项目之——智能家居项目的实现!
  • 基于PyTorch的食物图像分类实战:从数据处理到模型训练
  • AAA GitOps详解
  • n8n工作流自动化平台的实操:本地化高级部署
  • 浙大:优化视觉模型的过度思考
  • 【Godot】生命周期详解:从节点诞生到销毁的全流程解析
  • 软件工程实践
  • sonar-scanner在扫描JAVA项目时为什么需要感知.class文件
  • Redis持久化: