var operator_obj = services.NewOperator()
type OperatorHandler func(req interface{}, token *string) (interface{}, error)
// Token 验证中间件
func WithTokenValidation(handler OperatorHandler) OperatorHandler {
return func(req interface{}, token *string) (interface{}, error) {
token_detail, err := tools.ParseTokens(token)
fmt.Printf("tokenDetail:%+v",token_detail)
if err != nil {
return nil, err
}
// 可以将 tokenDetail 传递给业务处理函数
// 这里需要根据具体需求调整
return handler(req, token)
}
}
func OperatorList(r *http.Request)(resp interface{}, err error){
authorization := (*r).Header.Get(types.HEADER_AUTH)
var req = new(iapi.OperatorListReq)
if resp,err = ParseReq(r,&req,"获取操作者列表,前端参数错误",log_tag_operator);err != nil{
return
}
PageSetComm(&(req.PageReq))
list,err := WithTokenValidation(operator_obj.List,req,authorization)
return
}
services的定义:
func (o *Operator) List(req *iapi.OperatorListReq, token *string)(resp iapi.OperatorListResp,err error){
list,total,err := dao.OperatorList(req,10)
}
WithTokenValidation是一个函数中间件,OperatorList调用services的方法,WithTokenValidation(operator_obj.List,req,authorization),operator_obj.List是调用的services的方法,是调用的不对么,报错:
declared and not used: list
assignment mismatch: 2 variables but WithTokenValidation returns 1 value
too many arguments in call to WithTokenValidation
have (func(req *iapi.OperatorListReq, token *string) (resp iapi.OperatorListResp, err error), *iapi.OperatorListReq, string)
golang函数中间件
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
5条回答 默认 最新
檀越@新空间 2025-09-23 17:47关注下午好🌅🌅🌅
本答案参考通义千问你提到的错误信息非常关键,我们来逐步分析并解决这个问题。
问题分析
1. WithTokenValidation 的定义
func WithTokenValidation(handler OperatorHandler) OperatorHandler { return func(req interface{}, token *string) (interface{}, error) { token_detail, err := tools.ParseTokens(token) fmt.Printf("tokenDetail:%+v",token_detail) if err != nil { return nil, err } // 可以将 tokenDetail 传递给业务处理函数 // 这里需要根据具体需求调整 return handler(req, token) } }这个中间件接收一个
OperatorHandler类型的函数,并返回一个新的OperatorHandler函数。它接受两个参数:req interface{}和token *string,并返回(interface{}, error)。
2. operator_obj.List 的定义
假设
operator_obj.List是这样的:func (o *Operator) List(req *iapi.OperatorListReq, token *string) (resp iapi.OperatorListResp, err error) { list, total, err := dao.OperatorList(req, 10) return resp, err }这说明
operator_obj.List是一个方法,其签名是:func (o *Operator) List(req *iapi.OperatorListReq, token *string) (iapi.OperatorListResp, error)而
OperatorHandler的定义是:type OperatorHandler func(req interface{}, token *string) (interface{}, error)所以,
operator_obj.List并不完全匹配OperatorHandler的类型,因为它的参数和返回值与OperatorHandler不一致。
3. 调用 WithTokenValidation 的方式错误
你在
OperatorList中这样调用:list, err := WithTokenValidation(operator_obj.List, req, authorization)这是错误的,因为:
WithTokenValidation接收的是一个OperatorHandler(即一个函数),而不是直接调用该函数。- 你传入了三个参数:
operator_obj.List,req,authorization,但WithTokenValidation只接受一个参数(即handler)。
解决方案
✅ 步骤 1:适配 operator_obj.List 到 OperatorHandler
你需要将
operator_obj.List转换为符合OperatorHandler签名的函数。// 将 operator_obj.List 转换为 OperatorHandler func adaptOperatorList(req *iapi.OperatorListReq, token *string) (interface{}, error) { resp, err := operator_obj.List(req, token) return resp, err }
✅ 步骤 2:使用 WithTokenValidation 包装适配后的函数
// 使用 WithTokenValidation 包装适配后的函数 wrappedHandler := WithTokenValidation(adaptOperatorList)
✅ 步骤 3:调用包装后的函数
resp, err := wrappedHandler(req, &authorization)
最终修改后的代码示例
// 修改后的 OperatorList 函数 func OperatorList(r *http.Request) (resp interface{}, err error) { authorization := (*r).Header.Get(types.HEADER_AUTH) var req = new(iapi.OperatorListReq) if resp, err = ParseReq(r, &req, "获取操作者列表,前端参数错误", log_tag_operator); err != nil { return } PageSetComm(&(req.PageReq)) // 适配 operator_obj.List 到 OperatorHandler adaptedHandler := func(req interface{}, token *string) (interface{}, error) { reqTyped, ok := req.(*iapi.OperatorListReq) if !ok { return nil, errors.New("invalid request type") } return operator_obj.List(reqTyped, token) } // 使用中间件包装 wrappedHandler := WithTokenValidation(adaptedHandler) // 调用包装后的函数 result, err := wrappedHandler(req, &authorization) return result, err }
总结
| 问题 | 解决方案 | |------|----------| |
WithTokenValidation被错误地调用 | 改为只传入OperatorHandler,而不是直接调用 | |operator_obj.List不匹配OperatorHandler| 通过适配器函数将其转换为兼容的格式 | | 参数数量错误 | 正确理解中间件的使用方式 |
如果你有更多关于中间件设计或 Golang 类型转换的问题,欢迎继续提问!
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报