如何获取空接口的动态类型



我尝试在go-gin框架中测试请求数据的验证,到目前为止,我得到了运行良好的代码。

// RegisterEmailPasswordValidator it is used for validation and json marshalling
type RegisterEmailPasswordValidator struct {
Email    string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,gte=6,lte=30"`
}
// Validate used in views
func (v *RegisterEmailPasswordValidator) Validate( c *gin.Context) error {
if err := c.ShouldBindJSON(v); err != nil {
return err
}
return nil
}
// use it like this in my controller
var validator validations.RegisterEmailPasswordValidator
err := validator.Validate(c)

为了DRY,我尝试添加一个全局函数来验证所有结构的责任。我试着添加了一个空接口的函数,比如bellow。

// Validate used in views
func Validate(c *gin.Context, customValidator interface{}) error {   
if err := c.ShouldBindJSON(&customValidator); err != nil {
return err
}
return nil
}
// use it like this in my controller
var validator validations.RegisterEmailPasswordValidator
err := validations.Validate(c, &validator)

但当我将customValidator发送到ShouldBindJSON时,它不起作用。它使用空接口,而不是动态类型。

有没有任何方法可以在不提及其类型的情况下使用customValidator的动态类型?我试着反思
在这种情况下,有没有更好的方法来保持干燥?

您应该按原样传递接口,而不是指向接口的指针。像这样的东西:

// Validate used in views
func Validate(c *gin.Context, customValidator interface{}) error {   
if err := c.ShouldBindJSON(customValidator); err != nil {
return err
}
return nil
}
// use it like this in my controller
var validator validations.RegisterEmailPasswordValidator
err := validations.Validate(c, &validator)

原因是Go中的指针与C/C++中的指针不同,它们保留了类型和值引用。指向接口的指针不是指向它所持有的类型的指针,而是指向接口本身的指针,类型就是接口。在ShouldBindJSON中,函数试图通过反射获取对象,但它获取的是接口类型和引用,而不是validator的引用,因此它无法完成自己的工作,因为它需要一个类型,而不是接口。

最新更新