1. 変数と定数

Golangでは、変数と定数はプログラムにおいて非常に重要な役割を果たす2つの基本的な概念です。

  • 変数 はプログラム内でデータを格納するために使用される名前付き識別子です。Golangでは、var キーワードを使用して変数を宣言します。
  • 定数 はプログラム内で値を変更することができない識別子です。Golangでは、const キーワードを使用して定数を宣言します。

2. Golang変数の宣言と初期化

2.1 1つの変数の宣言と代入

Go言語では、var キーワードを使用して var 変数名 型 の形式で変数を宣言します。宣言後、変数には後続のコードで値を代入するか、宣言時に直接初期化することができます。例:

var age int // 整数変数 age を宣言
age = 25    // 変数に値を代入

var name string = "Alice" // 変数 name を宣言および初期化

2.2 複数の変数の宣言

Go言語では、複数の変数を同時に宣言することができ、これによりコードがより簡潔になります。一括宣言は通常、関数の冒頭またはパッケージレベルで行われます。例:

var (
    firstName, lastName string
    age                 int
)

firstName = "John"
lastName = "Doe"
age = 30

上記の一括宣言では、firstNamelastName は文字列として宣言され、age は整数です。

2.3 型推論と短い変数宣言

Go言語では、変数の型を明示的に指定する必要はありません。変数の宣言時に初期化式が提供されている場合、Goは変数の型を推論することができます。これを型推論と呼びます。:= を使用した短い変数宣言は、型推論に基づいて変数の宣言および初期化を簡素化することができます。例:

city := "Beijing" // 短い変数宣言を使用して同時に city を宣言および初期化
country := "China" // country は文字列型として推論されます

短い変数宣言は関数内でのみ使用でき、グローバルスコープでは使用できませんので注意してください。

2.4 関数外での変数の宣言

関数外で宣言された変数はパッケージレベルのスコープを持ちます。これらの変数はパッケージ全体で見え、アクセスできます。例:

var globalVar string = "私はグローバルです" // グローバル変数の宣言

func printGlobalVar() {
    fmt.Println(globalVar) // 関数内でグローバル変数にアクセス
}

グローバル変数はパッケージ内の任意の関数で共有することができますが、潜在的な名前の衝突や明確でない参照を避けるために注意して使用する必要があります。

ヒント: ここで基本的な関数コードを理解するだけで十分で、関数の詳細な説明は後のセクションで提供されます。

3. 基本データ型とゼロ値

3.1 Golangの基本データ型

Go言語では、各種の変数型が明示的な意味論と振る舞いの特性を提供しています。以下は一般的な基本データ型です:

  • intint8int16int32int64: 異なる範囲の整数
  • uintuint8uint16uint32uint64: 符号なし整数
  • float32float64: 浮動小数点数
  • bool: ブール値(true または false)
  • string: 文字列

3.2 ゼロ値の概念

Go言語では、変数は宣言後にその型のゼロ値で自動的に初期化されます。ゼロ値は、変数が明示的に初期化されていない場合の、対応する型のデフォルト値を指します。これは他の一部の言語では一般的ではありませんが、Goではすべての変数が常に有効な初期値を持つことを保証します。以下は各基本データ型のゼロ値です:

  • 整数のゼロ値は 0
  • 浮動小数点数のゼロ値は 0.0
  • ブール値のゼロ値は false
  • 文字列のゼロ値は空の文字列 ""

例:

var i int     // ゼロ値は 0
var f float64 // ゼロ値は 0.0
var b bool    // ゼロ値は false
var s string  // ゼロ値は ""

ゼロ値の概念を理解することは非常に重要であり、変数の初期化の動作を理解し、ヌルポインタや未初期化エラーを防ぐために使用することができます。

4. 変数のスコープ

4.1 ローカル変数

ローカル変数とは、関数内で定義された変数であり、その関数内でのみアクセス可能です。関数のパラメータもローカル変数に含まれます。ローカル変数は、作成された時点から関数の実行が完了するまで存在し、関数が呼び出されるたびに再作成されます。

func localVariableExample() {
    var localVariable int = 10 // これはローカル変数です
    fmt.Println(localVariable)
}

func main() {
    localVariableExample() // 出力: 10
    // fmt.Println(localVariable) // この行は、localVariableがここで見えないため、コンパイルエラーが発生します
}

上記の例では、localVariablelocalVariableExample 関数内でのみアクセス可能です。

4.2 グローバル変数

グローバル変数とは、関数の外で定義された変数であり、同じパッケージ内のどのファイルからでもアクセスできます。他のパッケージでグローバル変数を使用する場合は、変数名が Go のアクセス制御ルールに従って大文字で始まる必要があります。

package main

import "fmt"

var globalVariable int = 20 // これはグローバル変数です

func main() {
    fmt.Println(globalVariable) // 出力: 20
    changeGlobal()
    fmt.Println(globalVariable) // 出力: 30
}

func changeGlobal() {
    globalVariable = 30 // グローバル変数の値を変更
}

この例では、globalVariablemain 関数と changeGlobal 関数の両方で見えます。

5 定数の宣言と使用

5.1 const キーワード

const キーワードを使用して定数を定義します。定数は変更できない値であり、一度定義されるとその値を変更することはできません。定数は整数、浮動小数点数、真偽値、または文字列など、任意の基本データ型であることができます。

const Pi = 3.14 // 浮動小数点数の定数を宣言
const StrConst string = "Hello, World!" // 文字列定数を宣言

func main() {
    fmt.Println(Pi)
    fmt.Println(StrConst)
}

5.2 列挙定数

Go 言語には特定の列挙型はありませんが、iota キーワードを使用して列挙を実現できます。const ブロック内で、追加の定数宣言ごとに iota の値が 1 ずつ増加します。

const (
    Sunday = iota  // 0
    Monday         // 1
    Tuesday        // 2
    Wednesday      // 3
    Thursday       // 4
    Friday         // 5
    Saturday       // 6
)

func main() {
    fmt.Println(Sunday)    // 出力: 0
    fmt.Println(Saturday)  // 出力: 6
}

上記のコードは、曜日の列挙を宣言し、iotaconst ブロック内で 0 から初期化され、後続の宣言ごとに 1 ずつ増加します。

5.3 定数のスコープ

定数のスコープは変数と似ています。もし関数内で定数が定義されている場合、その定数のスコープはその関数に限定されます。もし関数の外(グローバル)で定数が定義されている場合、その定数のスコープはパッケージ全体になり、先頭が大文字であれば他のパッケージからアクセスできます。

定数のスコープを管理することにより、グローバルスコープの混乱を減らし、プログラムの保守性と可読性を向上させることができます。

const GlobalConst = "これはグローバル定数です"

func main() {
    const LocalConst = "これはローカル定数です"
    fmt.Println(GlobalConst)  // これは有効です
    fmt.Println(LocalConst)   // これは有効です
}

func anotherFunction() {
    // fmt.Println(LocalConst) // この行は、LocalConst がこの関数では見えないため、コンパイルエラーが発生します
    fmt.Println(GlobalConst)  // これは有効です
}

この例では、LocalConstmain 関数内でのみアクセスでき、一方で GlobalConst はパッケージ全体でアクセス可能です。