## What — 内部表現と外部表現の変換 エンコードとは、プログラム内部のデータ(Go の構造体など)を、送信・保存できる**バイト列**(JSON 文字列など)に変換すること。デコードはその逆で、受け取ったバイト列を内部のデータ構造に戻すこと。 なぜ変換が要るかというと、メモリ上の構造体はそのプロセスの中でしか意味を持たないから。ネットワークの向こうの相手やファイルに渡すには、言語に依存しない共通形式へ直す必要がある。 ```mermaid flowchart LR J["外部形式<br>JSON バイト列"] -->|"デコード(受け取った直後)"| S["内部形式<br>Go の構造体"] S -->|"エンコード(送る直前)"| J ``` 覚え方は接頭辞で持つ:**en- は「中に入れる」**(encase・enclose の仲間)=データを符号(code)に詰める。de- は「解く」(decipher・decompress の仲間)=符号を解いて取り出す。 ## How — ingestion は「入口でデコード、出口でエンコード」 データ取り込み(ingestion)の処理は、外部 API の JSON をデコードして構造体で加工し、次の送信先へエンコードして渡す、という往復で書ける。 ```go type User struct { ID int `json:"id"` Name string `json:"name"` } // デコード:API レスポンスのバイト列 → 構造体 var u User if err := json.Unmarshal(body, &u); err != nil { return err } // エンコード:加工した構造体 → 次へ送るバイト列 out, err := json.Marshal(u) ``` バッククォートの `json:"id"` は構造体タグで、JSON のキーと Go のフィールドの**対応表**になる。Go 側はフィールド名が大文字始まり(公開)でないと変換対象にならない点もセット。 > [!warning] > `json.Unmarshal` は、タグとキー名が一致しないフィールドを**エラーにせずゼロ値のまま**通す。ingestion だと「エラーは出ないのに値が全部空」という形で現れるので、取り込み結果が空のときはまずタグの typo を疑う。 > [!success] > エンコード=内部→外部形式、デコード=外部→内部。ingestion のコードは「入口で Unmarshal、出口で Marshal」の往復で読める。 ## 関連 - [[Go]] - [[Goスライスの len・cap・nil]] — nil スライスが JSON でどう出るかの話。エンコード時の隣の落とし穴