【问题标题】:How to get dynamic type of empty interface如何获取空接口的动态类型
【发布时间】:2020-12-07 16:37:03
【问题描述】:

我尝试在 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)

为了干脆,我尝试添加一个全局函数来验证所有结构的责任。我尝试添加一个空界面的函数,如下所示。

// 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 而不提及它的类型?我试过反射。
在这种情况下,有没有更好的方法来干燥?

【问题讨论】:

  • @ILoveReflection 我试过你的建议,有一个错误 json: Unmarshal(non-pointer validations.RegisterEmailPassword)
  • 我误解了代码。我看不到 Validate 函数在哪里使用。忽略我之前的评论。
  • 您不应将指针发送到您的函数的接口。另外我猜 ShouldBindJson 的输入是一个接口,而您已经有了一个接口,为什么要将指针传递给该接口?
  • @Mastisa 接受的答案正是我所建议的。也就是说,问题中的代码没有使用 Validate 函数,所以我仍然很困惑。
  • 我不完全记得你的建议,但你的建议有我提到的错误。

标签: validation go go-gin


【解决方案1】:

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

// 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 中,该函数尝试通过反射获取对象,但它获取的是接口类型和引用,而不是validators 引用,因此它无法完成它的工作,因为它需要一个类型,而不是一个接口。

【讨论】:

  • Go 中的指针与 C/C++ 中的指针相同。就是接口值不同。
猜你喜欢
  • 2023-01-19
  • 2020-10-23
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多