以下の内容はhttps://malsan.hatenablog.com/entry/2024/09/07/224154より取得しました。


【Go言語】意図的に0や空文字を使うとvalidatorが反応してしまう問題

TL;DR

必須チェックを行う場合は構造体の変数をポインタ型にすることで0や空文字を使ってもバリデーションエラーを返さないようにできます。

type Human struct {
    Name *string `validate:"required"`
    Age  *int    `validate:"required"`
}

遭遇した問題

Goで構造体をバリデーションを行っていたとき、Ageに0を入れるとバリデーションエラーを返してしまう問題に遭遇しました。

type Human struct {
    Name string `validate:"required"`
    Age  int    `validate:"required"`
}

func main() {
    h := Human{
        Name: "Taro",
        Age:  0, // 意図的に0を入れている
    }
    if err := validator.New().Struct(h); err != nil {
        var ve validator.ValidationErrors
        if errors.As(err, &ve) {
            for _, fe := range ve {
                fmt.Printf("フィールド %s が %s 違反です(値:%v)\n", fe.Field(), fe.Tag(), fe.Value())
        // フィールド Age が required 違反です(値:0)
            }
        }
    }
}

原因

Goが変数に与える初期値により、validatorが「値が与えられたのか、そうでなかったのか」を判別できなくなるから。

Goの変数の初期値について

Goの変数は宣言時に初期値が与えられます。初期値は型によって異なりますが、以下のようになっています。

  • 数値型: 0
  • bool型: false
  • string型: ""

validatorと初期値の問題

validatorを使って構造体のバリデーションを行うときに、0や""などの値を意図的に入れたとしても、validatorは「値が与えられなかった」と勘違いしてしまいます。

そのため、意図的に0を入れていたのにも関わらず、バリデーションエラーが返ってきたわけです。

解決策

構造体の変数をポインタ型にすることで0や空文字を使ってもバリデーションエラーを返さないようにできます。

type Human struct {
    Name *string `validate:"required"`
    Age  *int    `validate:"required"`
}

ポインタにすると値が未設定のとき値はnilになります。そのため、意図的に0や空文字を与えたか、そうでないかを判別できるようになります。

var i int
var j *int

fmt.Printf("%v\n", i)
fmt.Printf("%v\n", j)

// 0
// <nil>

そのため以下の場合、Ageに0を与えてもバリデーションエラーは返ってきません。

type Human struct {
    Name *string `validate:"required"`
    Age  *int    `validate:"required"`
}

func main() {
    h := Human{
        Name: "Taro",
        Age:  0,
    }
    if err := validator.New().Struct(h); err != nil {
        var ve validator.ValidationErrors
        if errors.As(err, &ve) {
            for _, fe := range ve {
                fmt.Printf("フィールド %s が %s 違反です(値:%v)\n", fe.Field(), fe.Tag(), fe.Value())
            }
        }
    }
}

参考

実用Go言語 : https://www.oreilly.co.jp/books/9784873119694/




以上の内容はhttps://malsan.hatenablog.com/entry/2024/09/07/224154より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14