Golang创建自定义验证器,执行接口的方法。

huangapple go评论82阅读模式
英文:

Golang create custom validator that executes method of an interface

问题

我正在尝试为gin创建自己的验证器,但我希望它是“通用的”,也就是说,我想要一个名为IsValid的接口:

type IsValid interface {
    IsValid() bool
}

然后,在一些字段中实现该接口,并使用binding:"IsValid"进行绑定。

但是我不知道如何编写自定义验证器来获取字段,将其转换为IsValid接口,然后执行isValid方法。

我正在使用go-playground验证器包:https://github.com/go-playground/validator

if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
    // 为isValid注册验证
    v.RegisterValidation("isValid", func(fl validator.FieldLevel) bool {
        isValidField := // TODO:做一些将其转换为该接口的操作
        return isValidField.IsValid()
    })
}
英文:

I am trying to create my own validator for gin, but I want it to be "generic", so let's say, I want to have an interface IsValid

type IsValid interface {
    IsValid() bool
}

, and make some structs to have binding:"IsValid" in some fields that implement that interface.

But I don't know how to write my custom validator to get the field, cast it to the IsValid interface, and then execute the isValid method.

I am using the go-playground validator package: https://github.com/go-playground/validator

if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
    // registering validation for isValid
    v.RegisterValidation("isValid", func(fl validator.FieldLevel) bool {
        isValidField := // TODO do something to cast it to that interface
        return isValidField.IsValid()
    })
}

答案1

得分: 1

FieldLevel 类型有以下方法:

// 返回当前用于验证的字段
Field() reflect.Value

reflect.Value 有以下方法:

func (v Value) Interface() (i any)

Interface 方法将 v 的当前值作为 interface{} 返回。等效于:

var i interface{} = (v 的底层值)

如果通过访问未导出的结构字段获取了该 Value,则会引发 panic。

你可以使用 类型断言interface{} / any 值用作更具体的接口,如下所示:

var i interface{} = something
var x = i.(MyInterface)

如果值 i 没有实现 MyInterface,则会引发 panic。为了检查这种情况,可以使用另一种形式:

var x, ok = i.(MyInterface)
if ok {
    // 使用 x
} else {
    // 类型转换失败
}

将它们组合起来,你的代码可能如下所示:

isValidField, ok := fl.Field().Interface().(IsValid)
英文:

The FieldLevel type has this method:

// returns current field for validation
Field() reflect.Value

reflect.Value has this method:

func (v Value) Interface() (i any)

> Interface returns v's current value as an interface{}. It is equivalent to:
>
> var i interface{} = (v's underlying value)
>
> It panics if the Value was obtained by accessing unexported struct fields.

You can use a type assertion to utilize an interface{} / any value as a more specific interface like this:

var i interface{} = something
var x = i.(MyInterface)

This will panic if the value i doesn't implement MyInterface. To check for that case, the alternate form can be used:

var x, ok = i.(MyInterface)
if ok {
    // use x
} else {
    // type conversion failed
}

Putting it together, your code would be something like this:

isValidField, ok := fl.Field().Interface().(IsValid)

huangapple
  • 本文由 发表于 2022年7月11日 16:03:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/72935418.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定