演習2-2

演習2-1で定義したHelloWorldを埋め込み,さらに別のメンバー変数lang(整数型)をもつ構造体MultilingalHelloを定義せよ.また,構造体MultilingalHelloの言語を設定するメソッドSetLanguageを作成せよ.このメソッドは,言語を表す整数型の引数を一つもつものとし,引数の値によって,メンバー変数の値を次のように設定するものとする.

0: lang=0 hello="Hello, World!"

1: lang=1 hello="こんにちは、世界。"

2: lang=2 hello="Bonan tagon"

解答例

  1. package main
  2. import "fmt"
  3. type HelloWorld struct {
  4. hello string
  5. }
  6. func (h *HelloWorld) SayHello() {
  7. fmt.Printf(h.hello+"\n")
  8. }
  9. func (h *HelloWorld) SetHello(hello string) {
  10. h.hello = hello
  11. }
  12. type MultilingalHello struct {
  13. HelloWorld
  14. lang int
  15. }
  16. func (m *MultilingalHello) SetLanguage(lang int) {
  17. m.lang = lang
  18. switch lang {
  19. case 0:
  20. m.hello = "Hello, World!"
  21. case 1:
  22. m.hello = "こんにちは、世界。"
  23. case 2:
  24. m.hello = "Bonan tagon"
  25. }
  26. }
  27. func main() {
  28. m := new(MultilingalHello)
  29. m.SayHello() // HelloWorldのメソッドSayHello,SetHelloをそのまま使える(継承のように)
  30. m.SetHello("Hello, World!")
  31. m.SayHello()
  32. m.SetLanguage(1) // もちろん新たに定義したメソッドも使える
  33. m.SayHello()
  34. m.SetLanguage(0)
  35. m.SayHello()
  36. m.SetLanguage(2)
  37. m.SayHello()
  38. m.HelloWorld.SayHello() // HelloWorldのメソッドを明示的に呼び出すこともできる
  39. }

解説

匿名フィールド

  • フィールドが型だけでフィールド名を指定せずに宣言されたときは匿名フィールドとなります(埋め込みフィールドとも呼ばれます).
  • 解答例では,HelloWorldがMultilingalHelloの匿名フィールドとして定義されています(17行目)
  • 匿名フィールド内のフィールドとメソッドは,その外側の型のフィールドとメソッドへ昇格されます.すなわち,継承のようなことができます.
  • 解答例では,HelloWorldのメソッドSetHello(),SayHello()をその外側の構造体MultilingalHelloのメソッドとして呼び出すことができます(35-37行目).
  • 匿名フィールドに関する詳細は,言語仕様の構造体型セレクタを参照してください.