英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论