Go 使用go-playground/validator
驗證struct的bool欄位required
時,設定值false時驗證失敗。
例如下面Employee.Deleted
設為false,加上validate tag required
驗證時會出現錯誤:
Key: 'Employee.Deleted' Error:Field validation for 'Deleted' failed on the 'required' tag
main.go
package main
import (
"fmt"
validator "github.com/go-playground/validator/v10"
)
type Employee struct {
Id int `validate:"required"`
Name string `validate:"required"`
Deleted bool `validate:"required"`
}
func main() {
emp := Employee{
Id: 1,
Name: "John",
Deleted: false,
}
err := validator.New().Struct(emp)
if err != nil {
fmt.Println(err)
}
}
原因出在required
對於基本型別的欄位是檢查值是否為非零值/非預設值(check field's value is non-zero/non-default value),而非字面意義上檢查值是否存在(因為基本型別欄位不可能是nil
)。也就是說,當欄位是基本型別且值為零值(預設值)則驗證失敗。
Employee.Deleted
為基本型別bool
,零值為false,所以當值為false時與零值相同,則required
驗證失敗。
查看可能的原始碼如下:
baked_in.go#L1499
// hasValue is the validation function for validating if the current field's value is not the default static value.
func hasValue(fl FieldLevel) bool {
field := fl.Field()
switch field.Kind() {
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
return !field.IsNil()
default:
if fl.(*validate).fldIsPointer && field.Interface() != nil {
return true
}
return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface() // check if field's value does not equal to zero value
}
}
在最後回傳的判斷field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
意思即為「欄位值是否為非零值」。
至於pointer欄位required
才確實是驗證是否存在(是否為nil
)。例如下面把Deleted
欄位改為pointer則通過驗證。
main.go
package main
import (
"fmt"
validator "github.com/go-playground/validator/v10"
)
type Employee struct {
Id int `validate:"required"`
Name string `validate:"required"`
Deleted *bool `validate:"required"`
}
func main() {
deleted := false
emp := Employee{
Id: 1,
Name: "John",
Deleted: &deleted,
}
err := validator.New().Struct(emp)
if err != nil {
fmt.Println(err)
}
}
沒有留言:
張貼留言