Go練習問題4-10:デコーディングを理解しよう

記事内に商品プロモーションを含む場合があります

Go言語の初心者向け問題4-10:デコーディングを理解しよう

この問題を解くために必要な知識:
レベル1~3の知識メモリ管理の基本エラーハンドリングカスタムエラーチャネルの選択タイムアウト処理パッケージinit関数ファイル操作エンコーディングデコーディングテストの書き方ベンチマークテストドキュメントの生成

<<前の問題 問題集Top 次の問題>>

Go言語の文法「デコーディング」とは





ここではデコーディングの意味や使い方を復習します。必要ない方はここをクリックして練習問題へ飛びましょう。

今回は、プログラミングにおいて非常に重要な概念である「エンコーディング」と「デコーディング」について解説します。

これらの用語は、一見すると難しそうに思えるかもしれませんが、実際にはとても身近で役立つ技術です。

エンコーディングとは?

エンコーディングとは、データをある形式から別の形式に変換することを指します。

Go言語では、例えば構造体(struct)というデータ形式をJSONという形式に変換することができます。JSONは、データをテキスト形式で表現するためのフォーマットで、ウェブAPIや設定ファイルなどで広く使われています。

Go言語でエンコーディングを行う際には、json.Marshal関数を使います。この関数は、GoのデータをJSON形式のバイト列に変換します。

jsonData, err := json.Marshal(v)

このように、Marshal関数に構造体vを渡すことで、そのデータをJSONに変換することができます。

デコーディングとは?

一方、デコーディングとはエンコーディングの逆の操作で、データを元の形式に戻すことを指します。

例えば、JSON形式のデータをGo言語の構造体に変換するのがデコーディングです。

Go言語では、json.Unmarshal関数を使ってデコードを行います。この関数は、JSON形式のバイト列をGoのデータ形式に変換します。

err := json.Unmarshal(data, &v)

上記のように、Unmarshal関数にJSONデータとそのデータを格納する構造体vへのポインタを渡すことで、データを元の構造体にデコードできます。

エンコーディングとデコーディングの使用例

以下は、Go言語でエンコーディングとデコーディングを実際にどのように行うかの例です。

package main

import (
	"encoding/json"
	"fmt"
)

type User struct {
	Name  string
	Email string
	Age   int
}

func main() {
	// 構造体をJSON形式にエンコード
	user := User{Name: "田中太郎", Email: "taro.tanaka@example.com", Age: 30}
	jsonData, err := json.Marshal(user)
	if err != nil {
		fmt.Println("エンコードエラー:", err)
		return
	}
	fmt.Println("エンコード結果:", string(jsonData))

	// JSONデータを構造体にデコード
	var decodedUser User
	err = json.Unmarshal(jsonData, &decodedUser)
	if err != nil {
		fmt.Println("デコードエラー:", err)
		return
	}
	fmt.Println("デコード結果:", decodedUser)
}

この例では、Userという構造体をJSON形式にエンコードし、それを再び構造体にデコードしています。この技術は、データの保存や通信の際に非常に役立ちます。

まとめ

エンコーディングとデコーディングは、データを異なる形式間で変換するための基本的かつ強力な技術です。Go言語では、これらを簡単に扱うことができる関数が用意されています。

JSON形式は特にウェブ開発でよく使われるため、この技術をマスターすることは、実際のプロジェクトで大いに役立つでしょう。 ​

Go練習問題4-10:JSONデータをデコードしてみよう

JSON形式の文字列をGo言語でデコードして、構造体に格納するプログラムを作成しましょう。

このプログラムは、ユーザー情報を含むJSONデータをデコードし、その内容を画面に表示します。

また、デコードされたデータを再度JSON形式にエンコードする機能も実装します。

この問題の要件

以下の要件に従ってコードを完成させてください。

  1. 以下のパッケージをインポートすること:
    • fmt: 標準入出力に使用
    • encoding/json: JSONのエンコード/デコードに使用
  2. Userという構造体を定義し、以下のフィールドを持つこと:
    • Name (string型): ユーザーの名前
    • Email (string型): ユーザーのメールアドレス
    • Age (int型): ユーザーの年齢
  3. JSON形式の文字列 {"name":"田中太郎","email":"taro.tanaka@example.com","age":30} をプログラム内に用意し、これをデコードして User 構造体に格納すること。
  4. デコードに json.Unmarshal 関数を使用すること。
  5. デコードしたユーザー情報を fmt.Println を使って画面に表示すること。
  6. User構造体を再度JSON形式にエンコードし、その結果を表示すること。

ただし、以下のような実行結果となるコードを書くこと。

*****↓↓正解コードの実行結果の例↓↓*****

$ go run main.go
デコードされたユーザー情報:
名前: 田中太郎
メールアドレス: taro.tanaka@example.com
年齢: 30
エンコードされたJSONデータ:
{"name":"田中太郎","email":"taro.tanaka@example.com","age":30}

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1.import文
 1-1. fmtパッケージのインポート
 1-2. encoding/jsonパッケージのインポート

2.User構造体の定義
 2-1. フィールド Name を定義(string型)
 2-2. フィールド Email を定義(string型)
 2-3. フィールド Age を定義(int型)

3.main関数
 3-1. JSON形式の文字列を定義(jsonData)
 3-2. User構造体の変数を宣言(user)
 3-3. json.Unmarshal関数を使ってJSONデータをデコード
 3-4. デコードされたデータを出力
 3-5. json.Marshal関数を使って構造体を再度JSON形式にエンコード
 3-6. エンコードされたデータを出力

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

package main

import (
	"fmt"
	"encoding/json"
)

// UserはJSONでエンコード/デコードするための構造体です
type User struct {
	Name  string `json:"name"`  // ユーザーの名前
	Email string `json:"email"` // ユーザーのメールアドレス
	Age   int    `json:"age"`   // ユーザーの年齢
}

func main() {
	// JSON文字列を作成します(エンコードされたデータ)
	jsonData := `{"name":"田中太郎","email":"taro.tanaka@example.com","age":30}`

	// デコードするためのUser型の変数を宣言します
	var user User

	/*【穴埋め問題1】
	ここにjson.Unmarshal関数を使用して、jsonDataをuser構造体にデコードするコードを書いてください。
	*/

	// デコード結果を出力します
	fmt.Println("デコードされたユーザー情報:")
	fmt.Println("名前:", user.Name)
	fmt.Println("メールアドレス:", user.Email)
	fmt.Println("年齢:", user.Age)

	/*【穴埋め問題2】
	ここにjson.Marshal関数を使用して、user構造体を再びJSON形式にエンコードするコードを書いてください。
	*/

	// エンコードされたJSONデータを出力します
	fmt.Println("エンコードされたJSONデータ:")
	/*【穴埋め問題3】
	ここにエンコードされたデータを文字列に変換して出力するコードを書いてください。
	*/
}

 

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

解答例と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

package main

import (
	"encoding/json"
	"fmt"
)

// UserはJSONでエンコード/デコードするための構造体です
type User struct {
	Name  string `json:"name"`  // ユーザーの名前
	Email string `json:"email"` // ユーザーのメールアドレス
	Age   int    `json:"age"`   // ユーザーの年齢
}

func main() {
	// JSON文字列を作成します(エンコードされたデータ)
	jsonData := `{"name":"田中太郎","email":"taro.tanaka@example.com","age":30}`

	// デコードするためのUser型の変数を宣言します
	var user User

	// json.Unmarshal関数を使ってJSONデータをデコードします
	err := json.Unmarshal([]byte(jsonData), &user)
	if err != nil {
		fmt.Println("デコード中にエラーが発生しました:", err)
		return
	}

	// デコード結果を出力します
	fmt.Println("デコードされたユーザー情報:")
	fmt.Println("名前:", user.Name)
	fmt.Println("メールアドレス:", user.Email)
	fmt.Println("年齢:", user.Age)

	// 構造体をJSON形式にエンコードします
	encodedData, err := json.Marshal(user)
	if err != nil {
		fmt.Println("エンコード中にエラーが発生しました:", err)
		return
	}

	// エンコードされたJSONデータを出力します
	fmt.Println("エンコードされたJSONデータ:")
	fmt.Println(string(encodedData))
}

正解コードの解説

このGoコードでは、JSON形式のデータを扱うための「エンコーディング」と「デコーディング」について学びます。

まずは、コードをブロックごとに分解し、それぞれの部分が何をしているのかを説明します。

import文の説明

import (
	"fmt"
	"encoding/json"
)

この部分では、コードで使うパッケージをインポートしています。

fmtは標準入力出力を扱うためのパッケージで、encoding/jsonはJSONデータのエンコードとデコードを行うためのパッケージです。

構造体の定義

type User struct {
	Name  string `json:"name"`
	Email string `json:"email"`
	Age   int    `json:"age"`
}

ここではUserという構造体を定義しています。構造体は複数のフィールド(データ)を持つことができるデータ型です。

この構造体は、ユーザーの名前、メールアドレス、年齢を表す3つのフィールドを持っています。

それぞれのフィールドには、JSONデータとの対応を示すタグが付けられています。

メイン関数の開始

func main() {
	// JSON文字列を作成します(エンコードされたデータ)
	jsonData := `{"name":"田中太郎","email":"taro.tanaka@example.com","age":30}`

main関数はプログラムのエントリーポイントです。この関数では、まずjsonDataというJSON形式の文字列を定義しています。これはエンコードされたデータです。

JSONデータのデコード

var user User
err := json.Unmarshal([]byte(jsonData), &user)
if err != nil {
	fmt.Println("デコード中にエラーが発生しました:", err)
	return
}

json.Unmarshal関数を使って、JSON形式の文字列jsonDataUser構造体にデコードしています。

Unmarshalとは、エンコードされたデータを元の形式(この場合はUser構造体)に変換する処理のことです。

もしデコード中にエラーが発生した場合、そのエラーを出力してプログラムを終了します。

デコード結果の表示

fmt.Println("デコードされたユーザー情報:")
fmt.Println("名前:", user.Name)
fmt.Println("メールアドレス:", user.Email)
fmt.Println("年齢:", user.Age)

ここでは、デコードされたデータを出力しています。

デコードが成功すると、JSONデータの内容がUser構造体の各フィールドに格納され、それを画面に表示します。

JSONデータのエンコード

encodedData, err := json.Marshal(user)
if err != nil {
	fmt.Println("エンコード中にエラーが発生しました:", err)
	return
}
fmt.Println("エンコードされたJSONデータ:")
fmt.Println(string(encodedData))

最後に、エンコードされたJSONデータを画面に表示します。この部分では、エンコードされたデータが文字列として出力されます。

<<前の問題 問題集Top 次の問題>>

この問題への質問・コメント

この問題を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    Go練習問題集へ戻る
    トップページへ戻る