在golang中从接口创建一个类型的变量

时间:2016-10-31 18:51:16

标签: go middleware go-gin

我正在尝试使用gin框架创建验证器/绑定器中间件。

这是模型

type LoginForm struct{
    Email string `json:"email" form:"email" binding:"email,required"`
    Password string `json:"password" form:"password" binding:"required"`
}

路由器

router.POST("/login",middlewares.Validator(LoginForm{}) ,controllers.Login)

中间件

func Validator(v interface{}) gin.HandlerFunc{
    return func(c *gin.Context){
        a := reflect.New(reflect.TypeOf(v))
        err:=c.Bind(&a)
        if(err!=nil){
            respondWithError(401, "Login Error", c)
            return
        }
        c.Set("LoginForm",a)
        c.Next()
    }
}

我是golang的新手。我理解问题是绑定到错误的变量。 还有其他方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

澄清我的评论,

不要使用MW的签名func Validator(v interface{}) gin.HandlerFunc,而是使用func Validator(f Viewfactory) gin.HandlerFunc

ViewFactory如果函数类型为type ViewFactory func() interface{}

MW可以改变

type ViewFactory func() interface{}

func Validator(f ViewFactory) gin.HandlerFunc{
    return func(c *gin.Context){
        a := f()
        err:=c.Bind(a) // I don t think you need to send by ref here, to check by yourself
        if(err!=nil){
            respondWithError(401, "Login Error", c)
            return
        }
        c.Set("LoginForm",a)
        c.Next()
    }
}

您可以像这样编写路由器

type LoginForm struct{
    Email string `json:"email" form:"email" binding:"email,required"`
    Password string `json:"password" form:"password" binding:"required"`
}
func NewLoginForm() interface{} {
   return &LoginForm{}
}
router.POST("/login",middlewares.Validator(NewLoginForm) ,controllers.Login)

更进一步,我认为您可能必须稍后了解相关信息,一旦获得interface{}值,就可以将其LoginForm改回v := some.(*LoginForm)

或者喜欢这样以获得更高的安全性

if v, ok := some.(*LoginForm); ok {
 // v is a *LoginForm
}

有关更深入的信息,请参阅golang类型断言。