Go言語の初心者向け問題3-☆1:レベル3の文法を総復習しよう
この問題を解くために必要な知識:
レベル1~2の知識、関数の定義と呼び出し、関数の戻り値と複数の戻り値、関数の可変長引数、無名関数(匿名関数)、クロージャ、構造体の定義とコンストラクタ関数、構造体の埋め込み、メソッドの定義とレシーバ、インターフェース、型アサーション、型スイッチ
<<前の問題 | 問題集Top |
次の問題>> |
Go練習問題3-☆1:レベル3の文法を総復習しよう
レベル3で学習した全ての文法について、身についているか確認しましょう。
この問題の要件
以下のコードをコピーし、コメントに従って完成させましょう。
package main import ( "fmt" ) // 基本的な情報を持つ構造体 /*【穴埋め問題1】 ここにBasicInfoという構造体を作成し、name(string型)とage(int型)というフィールドを持たせるコードを書いてください。 */ // メソッドを定義(レシーバはBasicInfo型) /*【穴埋め問題2】 ここにBasicInfo型のレシーバを持つShowBasicInfoメソッドを作成し、名前と年齢を表示するコードを書いてください。 */ // 職業を追加するための構造体 /*【穴埋め問題3】 ここにJobInfoという構造体を作成し、jobTitle(string型)とsalary(int型)というフィールドを持たせるコードを書いてください。 */ // 構造体の埋め込みを使ってBasicInfoとJobInfoを持つEmployee構造体を作成 /*【穴埋め問題4】 ここにEmployeeという構造体を作成し、BasicInfoとJobInfoを埋め込むコードを書いてください。 */ // メソッドを定義(レシーバはEmployee型) /*【穴埋め問題5】 ここにEmployee型のレシーバを持つShowEmployeeInfoメソッドを作成し、BasicInfoとJobInfoの情報を表示するコードを書いてください。 */ // 複数の戻り値を返す関数 /*【穴埋め問題6】 ここにaddAndSubtractという関数を作成し、2つの整数を受け取り、それらの和と差を返すコードを書いてください。 */ // 可変長引数を使用する関数 /*【穴埋め問題7】 ここにsumという関数を作成し、可変長引数を使用して整数の合計を返すコードを書いてください。 */ func main() { // Employee構造体の初期化 /*【穴埋め問題8】 ここにEmployee構造体を初期化し、BasicInfoに名前と年齢を、JobInfoに職業と給料を代入するコードを書いてください。 */ // Employeeの情報を表示 /*【穴埋め問題9】 ここにShowEmployeeInfoメソッドを呼び出してEmployeeの情報を表示するコードを書いてください。 */ // 関数で複数の戻り値を取得 /*【穴埋め問題10】 ここにaddAndSubtract関数を呼び出し、結果をsumResultとdiffResultに格納するコードを書いてください。 その結果を表示するコードも書いてください。 */ // 可変長引数を使った関数の呼び出し /*【穴埋め問題11】 ここにsum関数を呼び出して、合計値をtotalSumに格納し、その結果を出力するコードを書いてください。 */ // 無名関数(匿名関数)の使用 /*【穴埋め問題12】 ここに無名関数を使って「こんにちは、匿名関数です!」というメッセージを出力するコードを書いてください。 */ // クロージャの使用 /*【穴埋め問題13】 ここにincrementという関数を使ってクロージャを生成し、カウントを表示するコードを書いてください。 */ // 型アサーションの例 /*【穴埋め問題14】 ここに型アサーションを使って、変数iの型がstringかどうかを判定し、成功したらその値を表示するコードを書いてください。 */ // 型スイッチの例 /*【穴埋め問題15】 ここに型スイッチを使って、変数xの型を判定し、その結果に応じてメッセージを表示するコードを書いてください。 */ }
*****↓↓正解コードの実行結果の例↓↓*****
名前: 太郎, 年齢: 30 職業: エンジニア, 給料: 5000000円 和: 15, 差: 5 合計: 15 無名関数からのメッセージ: こんにちは、匿名関数です! クロージャでのカウント: 1 クロージャでのカウント: 2 型アサーション成功: 型アサーションの例 xはint型です。値: 42
解答例と解説
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
package main import ( "fmt" ) // 基本的な情報を持つ構造体 type BasicInfo struct { name string age int } // メソッドを定義(レシーバはBasicInfo型) func (b BasicInfo) ShowBasicInfo() { fmt.Printf("名前: %s, 年齢: %d\n", b.name, b.age) } // 職業を追加するための構造体 type JobInfo struct { jobTitle string salary int } // 構造体の埋め込みを使ってBasicInfoとJobInfoを持つEmployee構造体を作成 type Employee struct { BasicInfo // 埋め込み JobInfo // 埋め込み } // メソッドを定義(レシーバはEmployee型) func (e Employee) ShowEmployeeInfo() { e.ShowBasicInfo() // 埋め込まれた構造体のメソッドを呼び出し fmt.Printf("職業: %s, 給料: %d円\n", e.jobTitle, e.salary) } // 複数の戻り値を返す関数 func addAndSubtract(a, b int) (int, int) { return a + b, a - b } // 可変長引数を使用する関数 func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total } func main() { // Employee構造体の初期化 employee := Employee{ BasicInfo: BasicInfo{name: "太郎", age: 30}, JobInfo: JobInfo{jobTitle: "エンジニア", salary: 5000000}, } // Employeeの情報を表示 employee.ShowEmployeeInfo() // 関数で複数の戻り値を取得 sumResult, diffResult := addAndSubtract(10, 5) fmt.Printf("和: %d, 差: %d\n", sumResult, diffResult) // 可変長引数を使った関数の呼び出し totalSum := sum(1, 2, 3, 4, 5) fmt.Printf("合計: %d\n", totalSum) // 無名関数(匿名関数)の使用 func(message string) { fmt.Println("無名関数からのメッセージ:", message) }("こんにちは、匿名関数です!") // クロージャの使用 increment := func() func() int { counter := 0 return func() int { counter++ return counter } } inc := increment() fmt.Println("クロージャでのカウント:", inc()) fmt.Println("クロージャでのカウント:", inc()) // 型アサーションの例 var i interface{} = "型アサーションの例" s, ok := i.(string) if ok { fmt.Println("型アサーション成功:", s) } // 型スイッチの例 var x interface{} = 42 switch v := x.(type) { case int: fmt.Println("xはint型です。値:", v) case string: fmt.Println("xはstring型です。値:", v) default: fmt.Println("xは不明な型です。") } }
正解コードの解説
基本情報構造体の定義
type BasicInfo struct { name string age int }
BasicInfo
は名前(name
)と年齢(age
)を持つシンプルな構造体です。
struct
はGoでデータをまとめるための型で、オブジェクト指向の「クラス」のように使うことができます。
BasicInfoのメソッド定義
func (b BasicInfo) ShowBasicInfo() { fmt.Printf("名前: %s, 年齢: %d\n", b.name, b.age) }
ShowBasicInfo
メソッドは、BasicInfo
のデータを表示します。
メソッドのレシーバー((b BasicInfo)
)によって、このメソッドはBasicInfo
型に属することが明示されています。
fmt.Printf
は、フォーマットに従って文字列を出力するための関数です。
職業情報構造体の定義
type JobInfo struct { jobTitle string salary int }
JobInfo
は職業タイトル(jobTitle
)と給料(salary
)を持つ構造体です。
これもBasicInfo
と同様に、職業に関する情報を1つのデータとしてまとめています。
Employee構造体の定義と構造体の埋め込み
type Employee struct { BasicInfo // 埋め込み JobInfo // 埋め込み }
Employee
は、BasicInfo
とJobInfo
を埋め込んでいます。
Goでは「構造体の埋め込み」を使って、ある構造体のフィールドやメソッドを別の構造体に引き継ぐことができます。
これにより、Employee
は名前・年齢・職業・給料というすべての情報を持つことになります。
Employeeのメソッド定義
func (e Employee) ShowEmployeeInfo() { e.ShowBasicInfo() fmt.Printf("職業: %s, 給料: %d円\n", e.jobTitle, e.salary) }
ShowEmployeeInfo
は、Employee
の全体の情報(名前、年齢、職業、給料)を表示するメソッドです。
e.ShowBasicInfo()
とすることで、Employee
に埋め込まれたBasicInfo
のメソッドを呼び出しています。
複数の戻り値を返す関数
この関数は、2つの整数a
とb
を受け取り、それらの和と差を返します。
Goでは、1つの関数で複数の戻り値を返すことができ、(int, int)
と指定することで和と差の両方を返しています。
可変長引数を持つ関数
func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total }
sum
関数は、任意の数の整数を受け取り、その合計を返します。...int
という書き方は可変長引数を意味し、引数の数が不定の場合に使います。
Employeeの初期化と情報表示
employee := Employee{ BasicInfo: BasicInfo{name: "太郎", age: 30}, JobInfo: JobInfo{jobTitle: "エンジニア", salary: 5000000}, } employee.ShowEmployeeInfo()
ここでは、Employee
のインスタンスを初期化し、名前と職業などの情報を設定しています。
そして、ShowEmployeeInfo
メソッドを呼び出して情報を表示しています。
無名関数(匿名関数)の使用
func(message string) { fmt.Println("無名関数からのメッセージ:", message) }("こんにちは、匿名関数です!")
無名関数は、名前を持たない関数です。ここでは、その場限りの関数を定義してすぐに呼び出す形で使っています。
クロージャの使用
increment := func() func() int { counter := 0 return func() int { counter++ return counter } } inc := increment() fmt.Println("クロージャでのカウント:", inc()) fmt.Println("クロージャでのカウント:", inc())
クロージャは、関数がその外の変数を覚えている機能です。
ここでは、increment
関数の中で定義されたcounter
がクロージャ内で保持され、呼び出されるたびにcounter
の値が増えていきます。
型アサーションの例
var i interface{} = "型アサーションの例" s, ok := i.(string) if ok { fmt.Println("型アサーション成功:", s) }
interface{}
型は任意の型を受け入れる型です。
型アサーションを使って、その型がstring
かどうかを確認し、成功した場合には値を取り出します。
型スイッチの例
var x interface{} = 42 switch v := x.(type) { case int: fmt.Println("xはint型です。値:", v) case string: fmt.Println("xはstring型です。値:", v) default: fmt.Println("xは不明な型です。") }
型スイッチは、ある変数がどの型かを判定する構文です。
このコードでは、x
がint
かstring
か、あるいはその他の型かを判断して適切なメッセージを表示しています。
<<前の問題 |
問題集Top |
次の問題>> |
この問題への質問・コメント
この問題を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。