0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

omitempty を超えて:Go 1.24 における omitzero の理解

Posted at

表紙

前書き

Go 1.24 バージョンでは、encoding/json パッケージに omitzero タグが新たに追加され、ゼロ値フィールドの無視に関する動作がより明確かつカスタマイズ可能になりました。この記事では、omitzero タグの使用方法について詳しく解説します。

omitzero タグ

omitzero タグは、Go オブジェクトを JSON にシリアライズする際に、どのゼロ値フィールドを無視するかを制御するために使用されます。omitempty タグとは異なり、omitempty は空値(empty value)を無視します。一方で、ゼロ値(zero value)と空値は似ているようで、Go においては同一ではありません。例えば:

  • time.Time 型の場合、ゼロ値は "0001-01-01T00:00:00Z" であり、これは空値とは見なされません。
  • スライスフィールド IntSlice []int においては、値が [] または nil の場合、どちらも空値と見なされます。

なぜ omitzero を使うのか

  • 精密な制御:空値ではなく、明確にゼロ値フィールドを無視できます。
  • カスタマイズ可能な制御IsZero() bool メソッドを使用することで、フィールドのゼロ値の判定ロジックをカスタマイズできます。

omitzero タグの使用方法

package main

import (
  "encoding/json"
  "fmt"
  "time"
)

type User struct {
  Name    string    `json:"name,omitzero"`
  Age     int       `json:"age,omitzero"`
  Hobbies []string  `json:"hobbies,omitzero"`
  BornAt  time.Time `json:"born_at,omitzero"`
}

func main() {
  user := User{
    Name:    "Leapcell",
    Age:     18,
    Hobbies: []string{},
  }

  bytes, _ := json.MarshalIndent(user, "", "  ")
  fmt.Println(string(bytes))
}

string(bytes) を出力すると、以下のような JSON 結果になります:

{
  "name": "Leapcell",
  "age": 18,
  "hobbies": []
}

もし omitempty タグを使用した場合、hobbies フィールドは省略されます。しかし、たとえ born_at がゼロ値であっても、"born_at": "0001-01-01T00:00:00Z" のようにシリアライズされます。omitzero タグを使用することで、どのフィールドが無視されるかをより正確に制御でき、ゼロ値フィールドのみを除外することが可能になります。

IsZero() bool メソッド

IsZero() bool メソッドは、フィールドのゼロ値を判断するロジックをカスタマイズするために使われます。あるフィールドのゼロ値の判定方法を変更したい場合、そのフィールドに対して IsZero メソッドを実装することができます。以下はその一例です:

package main

import (
  "encoding/json"
  "fmt"
  "time"
)

type Age int

func (age *Age) IsZero() bool {
  return *age <= 0
}

type User struct {
  Name    string    `json:"name,omitzero"`
  Age     Age       `json:"age,omitzero"`
  Hobbies []string  `json:"hobbies,omitzero"`
  BornAt  time.Time `json:"born_at,omitzero"`
}

func main() {
  user := User{
    Name:    "Leapcell",
    Age:     -1,
    Hobbies: []string{},
  }

  bytes, _ := json.MarshalIndent(user, "", "  ")
  fmt.Println(string(bytes))
}

この例では、Age フィールドは IsZero メソッドを実装しており、ゼロ値の判定ロジックを制御しています。もし Age が 0 以下であれば、IsZerotrue を返し、そのフィールドは無視されます。出力結果は以下の通りです:

{
  "name": "Leapcell",
  "hobbies": []
}

まとめ

Go 言語において、omitzero タグを使用することで、無視されるフィールドを精密に制御することができ、ゼロ値フィールドのみを除外することが可能になります。また、IsZero メソッドを実装することにより、フィールドごとにゼロ値の判定ロジックをカスタマイズでき、様々なシリアライズ要件に対応することができます。


私たちはLeapcell、Goプロジェクトのホスティングの最適解です。

Leapcell

Leapcellは、Webホスティング、非同期タスク、Redis向けの次世代サーバーレスプラットフォームです:

複数言語サポート

  • Node.js、Python、Go、Rustで開発できます。

無制限のプロジェクトデプロイ

  • 使用量に応じて料金を支払い、リクエストがなければ料金は発生しません。

比類のないコスト効率

  • 使用量に応じた支払い、アイドル時間は課金されません。
  • 例: $25で6.94Mリクエスト、平均応答時間60ms。

洗練された開発者体験

  • 直感的なUIで簡単に設定できます。
  • 完全自動化されたCI/CDパイプラインとGitOps統合。
  • 実行可能なインサイトのためのリアルタイムのメトリクスとログ。

簡単なスケーラビリティと高パフォーマンス

  • 高い同時実行性を容易に処理するためのオートスケーリング。
  • ゼロ運用オーバーヘッド — 構築に集中できます。

ドキュメントで詳細を確認!

Try Leapcell

Xでフォローする:@LeapcellHQ


ブログでこの記事を読む

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?