简体   繁体   中英

Golang create custom validator that executes method of an interface

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()
    })
}

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM