🦦

Go言語入門: 25の予約済キーワードとコードサンプル

2023/09/03に公開

はじめに

言語仕様の理解を深める一歩として、25の予約語とSampleコードをまとめました。
予約語を理解することで、Go言語の理解を深めます。
Go言語を学んでいる方にとって、この記事は言語仕様の理解を深めるための一歩となることでしょう。

予約済キーワード一覧(25個)

Go言語で以下キーワードは予約されており、識別子として使用することができません。

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

https://go.dev/ref/spec#Keywords

以降それぞれカテゴリ別にSampleコードを記述しました。

  • パッケージとインポート
  • 関数と遅延実行
  • ループと条件制御
  • データ型と変数宣言
  • データ構造
  • ゴールーチン (Goroutines) と非同期処理

パッケージとインポート

1. package: Goプログラムが属するパッケージを宣言するために使用

2. import: 外部のパッケージをインポートするために使用され、他のGoプログラムを再利用

main.go
package main

import "hello" //helloパッケージをimport

func main() {
    hello.SayHello()//外部パッケージのSayHelloを実行
}
hello.go
package hello //パッケージ名をhelloと宣言

import "fmt"//フォーマット関連の機能を提供する標準パッケージをimport

func SayHello() {
    fmt.Println("from hello")
}

プログラムを実行すると"from hello"というメッセージが出力されます。

関数と遅延実行

3. func:関数を宣言するために使用されます。関数型言語であるGo言語の中核となる要素の一つ

4. defer: 関数の実行を遅延させるために使用され、関数の終了時に実行

5. return: 関数から値を返すために使用

package main

import "fmt"

// 関数宣言
func Hello() {
    fmt.Println("Hello, World!")
}

// 関数に引数を渡し、戻り値を返す
func add(a, b int) int {
    return a + b
}

func main() {
    // 関数を呼び出す
    Hello()

    // 関数に引数を渡して結果を受け取る
    result := add(3, 5)
    fmt.Println("3 + 5 =", result)

    // deferを使用して関数の遅延実行を設定
    defer fmt.Println("最後に出力")

    fmt.Println("先に出力")
}
出力結果
Hello, World!
3 + 5 = 8 
先に出力  
最後に出力

ループと条件制御

6. if: 条件文を宣言するために使用され、指定条件に応じて後続ブロックが実行

7. else: 条件文(if文)で条件が偽の場合に実行されるブロックを指定するために使用

package main

import "fmt"

func main() {
    x := 10

    if x > 5 {
        fmt.Println("xは5より大きい")
    } else {
        fmt.Println("xは5以下")
    }
}
出力結果
xは5より大きい

8. for: ループを宣言するために使用

9. continue: 現在のループの反復をスキップするために使用

package main

import "fmt"

func main() {
    for i := 0; i < 5; i++ {
        if i == 2 {
            continue // 2の場合はスキップ
        }
        fmt.Println(i)
    }
}
出力結果
0
1
3
4

10. break: for文から抜け出すために使用

package main

import "fmt"

func main() {
    for i := 1; i <= 5; i++ {
        if i == 3 {
            fmt.Println("ループ中断")
            break
        }
        fmt.Println("ループ: ", i)
    }
}
出力結果
ループ:  1
ループ:  2
ループ中断

11. switch: 条件分岐を実現するために使用され、複数ケースの中から適切なブロックが実行

12. case: switch文で特定条件に対する処理を指定するために使用

13. default: switch文でどのケースにも一致しない場合に実行されるブロックを指定するために使用

package main

import "fmt"

func main() {
    day := "Tuesday"

    switch day {
    case "Monday":
        fmt.Println("月曜日")
    case "Tuesday":
        fmt.Println("火曜日")
    case "Wednesday":
        fmt.Println("水曜日")
    default:
        fmt.Println("その他")
    }
}
出力結果
火曜日

14. fallthrough: switch文内のケース間でフォールスルー(次のケースを実行)を許可するために使用。特別ケースで必要な場合に限定的に使用

package main

import "fmt"

func main() {
    num := 1

    switch num {
    case 1:
        fmt.Println("1番")
        fallthrough
    case 2:
        fmt.Println("2番")
        fallthrough
    case 3:
        fmt.Println("3番")
    default:
        fmt.Println("その他")
    }
}

出力結果
123

15. goto: プログラム内で指定ラベルへジャンプするために使用。よほどのことがない限りは避けるべき

package main

import "fmt"

func main() {
    x := 0
Loop: // ラベル
    for x < 5 {
        if x == 3 {
            x++
			fmt.Println("goto")
            goto Loop // 指定ラベルにジャンプ
        }
        fmt.Println(x)
        x++
    }
}
出力結果
0
1
2
goto
4

データ型と変数宣言

16. const: 定数を宣言するために使用(定数は値の変更が不可)

17. type: 新しいデータ型を宣言するために使用(structやinterfaceの型定義にも使用)

18. var: 変数を宣言するために使用(変数の型を指定)

package main

import "fmt"

func main() {
    // 定数の宣言
    const pi = 3.14159
	// pi = 3; 代入不可

    // 変数の宣言と初期化
    var name string = "hogehoge taro"
    var age int = 30
    fmt.Println("名前:", name, " 年齢:", age)

    // 新しいデータ型の宣言(独自の型を定義)
    type Celsius float64
    var temperature Celsius = 25.5
    fmt.Println("摂氏", temperature, " 度")
}

出力結果
名前: hogehoge taro  年齢: 30
摂氏 25.5

データ構造

19. map: キーと値のペアを保持するデータ構造(マップ)を宣言するために使用

20. range: スライスやマップなどのデータ構造を反復処理するために使用

package main

import "fmt"

func main() {
    // マップ(キーと値のペアを保持するデータ構造)の宣言
    colors := map[string]string{
        "red":    "#FF0000",
        "green":  "#00FF00",
        "blue":   "#0000FF",
    }

    // rangeによるマップの反復処理
    for key, value := range colors {
        fmt.Printf("Key: %s, Value: %s\n", key, value)
    }

    // スライスの宣言
    numbers := []int{1, 2, 3, 4, 5}

    // rangeによるスライスの反復処理
    for index, number := range numbers {
        fmt.Printf("Index: %d, Number: %d\n", index, number)
    }
}

出力結果
Key: red, Value: #FF0000
Key: green, Value: #00FF00
Key: blue, Value: #0000FF
Index: 0, Number: 1
Index: 1, Number: 2
Index: 2, Number: 3
Index: 3, Number: 4
Index: 4, Number: 5

21. interface: インターフェースを宣言するために使用され、抽象化とポリモーフィズムをサポート(特定のメソッドセットを持つ型を表現)

22. struct: 構造体を宣言するために使用され、関連する異なる型のフィールドをまとめるために使用

package main

import "fmt"

// インターフェースの宣言
type Speaker interface {
    SpeakName() string
    SpeakAge() string
}

// 名前を言うメソッド
func (p Person) SpeakName() string {
    return fmt.Sprintf("私の名前は%sです。", p.Name)
}
// 年齢を言うメソッド
func (p Person) SpeakAge() string {
    return fmt.Sprintf("私の年齢は%d歳です。", p.Age)
}

// 構造体定義
type Person struct {
    Name string
    Age  int
}

func main() {
    // 構造体作成
    person := Person{
        Name: "hogehoge",
        Age:  30,
    }

    // インターフェースに構造体を代入
    var sp Speaker
    sp = person

    // インターフェースを通じて年齢と名前を表示
    fmt.Println(sp.SpeakName())
    fmt.Println(sp.SpeakAge()) 
}

出力結果
私の名前はhogehogeです。
私の年齢は30歳です。

ゴールーチン (Goroutines) と非同期処理

23. go: 新しいgoroutineを起動して非同期に関数を実行するために使用

24. chan: チャネル(goroutine間でデータを通信するための機能)を宣言するために使用

package main

import (
	"fmt"
	"time"
)

func reciever(c chan int) {
	for {
		i := <-c
		fmt.Println(i)
	}
}

func main() {

	// チャネルを作成
	ch1 := make(chan int)
	ch2 := make(chan int)

	// 2 つのgoroutineを起動して reciever 関数を実行
	go reciever(ch1)
	go reciever(ch2)

	i := 1
	for i < 5 {
		// チャネルに値を送信
		ch1 <- i * 1
		ch2 <- i * -1
		time.Sleep(time.Second) // 1秒待機
		i++
	}
	// goroutine終了
	close(ch1) 
	close(ch2)
}
出力結果
1
-1
-2
2
-3
3
-4
4

25. select: チャネル通信の複数の操作を待機し、最初に準備ができたものを実行するために使用

package main

import (
	"fmt"
	"time"
)

func main() {
	// チャネルを作成
	ch1 := make(chan int)
	ch2 := make(chan int)

	// goroutine1: チャネルにデータを送信
	go func() {
		time.Sleep(time.Second)
		ch1 <- 1
	}()

	// goroutine2: チャネルにデータを送信
	go func() {
		time.Sleep(time.Second)
		ch2 <- 2
	}()

	// selectステートメントで最初の到達したチャネルを操作
	select {
	case val := <-ch1:
		fmt.Println("ch1からデータを受信:", val)
	case val := <-ch2:
		fmt.Println("ch2からデータを受信:", val)
	// default:
	// 	fmt.Println("データ受信なし") //条件が実行可能でない場合に実行されるブロックも設計できる
	}
}
出力結果
ch2からデータを受信: 2

参考

https://go.dev/
https://go.dev/doc/
https://go.dev/tour/welcome/1

Discussion