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

Creating a variable of type from interface in golang

我正在尝试使用 gin 框架在 go 中创建 validator/binder 中间件。

这是模型

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 很陌生。我知道问题出在绑定到错误的变量上。 还有其他解决方法吗?

澄清我的评论,

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

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

可以更改分子量,因此

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{} 值,您可以像这样 v := some.(*LoginForm) 将其恢复为 LoginForm

或像这样更安全

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

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