第3章 基本文法

基本的な構文

  • 変数の宣言と初期化: varキーワードを使って変数を宣言し、値を割り当てます。
  • データ型: 基本的なデータ型にはint, float64, string, boolがあります。
  • 短縮形: :=を使用して、変数の宣言と初期化を同時に行います。
package main

import "fmt"

func main() {
    var number int = 10              // 整数型の変数
    var decimal float64 = 3.14       // 浮動小数点型の変数
    var text string = "こんにちは"   // 文字列型の変数
    var isTrue bool = true           // ブール型の変数

    shortForm := "簡単な宣言"         // 短縮形での変数宣言

    fmt.Println(number, decimal, text, isTrue, shortForm)
}

データ型

整数型

intuintは、マシンのアーキテクチャに依存したサイズ(32ビットまたは64ビット)を持ちます。

int8, int16, int32, int64といった型は、それぞれ8, 16, 32, 64ビットのサイズを持ちます。

var a int = 10
var b int64 = 5000000000
fmt.Println(a, b) // 出力: 10 5000000000


浮動小数点型

float32float64があり、それぞれ32ビットと64ビットの浮動小数点数を表します。

var c float32 = 3.14
var d float64 = 2.718281828
fmt.Println(c, d) // 出力: 3.14 2.718281828


文字列型

文字列はstring型で表され、イミュータブル(変更不可)です。

var e string = "こんにちは"
fmt.Println(e) // 出力: こんにちは


ブール型

真偽値を表すbool型があり、trueまたはfalseの値を取ります。

var f bool = true
fmt.Println(f) // 出力: true


配列

固定長で、同じ型の要素を持ちます。

var g [3]int = [3]int{1, 2, 3}
fmt.Println(g) // 出力: [1 2 3]


スライス

可変長で、配列よりも柔軟な操作が可能です。

var h []int = []int{4, 5, 6}
fmt.Println(h) // 出力: [4 5 6]


マップ

キーと値のペアを保持するデータ構造です。

var i map[string]int = map[string]int{"apple": 5, "banana": 2}
fmt.Println(i) // 出力: map[apple:5 banana:2]


構造体

異なる型のデータを一つの単位で扱うためのカスタム型です。

type Person struct {
    Name string
    Age  int
}

var j Person = Person{Name: "Alice", Age: 30}
fmt.Println(j) // 出力: {Alice 30}


ポインタ

ポインタはメモリ上のアドレスを指し示します。これにより、直接的なメモリ操作や他の変数への参照が可能になります。

ポインタを使うことで、関数間でデータを効率的に受け渡すことができます。

var x int = 10
var p *int = &x // xのアドレスをpに格納
fmt.Println(*p) // pが指すメモリの値(10)を出力


ルーン型

ルーンはint32型と同等で、Unicodeのコードポイントを表すのに使われます。

文字列内の個別のUnicode文字を扱う際に使用します。

var r rune = 'あ'
fmt.Println(r) // 出力: Unicodeコードポイント


インターフェース

インターフェースは、特定のメソッドセットを持つ任意の型を表します。

多様性と柔軟性を提供し、異なる型が共通のインターフェースを実装できます。

type Geometry interface {
    Area() float64
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

var g Geometry = Circle{Radius: 5}
fmt.Println(g.Area()) // 出力: 円の面積


関数型

Goでは関数も型として扱うことができ、変数に関数を代入したり、引数や戻り値として関数を使うことができます。

func add(x, y int) int {
    return x + y
}

var myFunc func(int, int) int = add
result := myFunc(2, 3)
fmt.Println(result) // 出力: 5


型の変換

Goにおける型の変換(型キャスト)は、あるデータ型の変数を別のデータ型に変換する際に使用されます。Goは静的型付け言語であるため、異なる型間の変換には明示的な型変換が必要です。以下に具体的な事例を示します。

整数型から浮動小数点型への変換

整数型(例:int)の変数を浮動小数点型(例:float64)に変換する例です。

package main

import (
    "fmt"
)

func main() {
    var i int = 42
    var f float64 = float64(i) // int型からfloat64型へ変換
    fmt.Println(f)            // 出力: 42(ただしfloat64型)
}


整数型間の変換

異なるサイズの整数型間での変換の例です。

package main

import (
    "fmt"
)

func main() {
    var a int32 = 100
    var b int64 = int64(a) // int32型からint64型へ変換
    var c int8 = int8(a)   // int32型からint8型へ変換(オーバーフローの可能性あり)

    fmt.Println(b) // 出力: 100
    fmt.Println(c) // 出力: 100(ただしint8型の範囲内であること)
}


浮動小数点型から整数型への変換

浮動小数点型(例:float64)の変数を整数型(例:int)に変換する例です。この変換では小数点以下が切り捨てられます。

package main

import (
    "fmt"
)

func main() {
    var f float64 = 42.5
    var i int = int(f) // float64型からint型へ変換
    fmt.Println(i)     // 出力: 42(小数点以下が切り捨てられる)
}


浮動小数点型間の変換

異なるサイズの浮動小数点型間での変換の例です。

package main

import (
    "fmt"
)

func main() {
    var f1 float32 = 3.14
    var f2 float64 = float64(f1) // float32型からfloat64型へ変換

    fmt.Println(f2) // 出力: 3.14(ただしfloat64型)
}


文字列とバイトスライスの相互変換

文字列をバイトスライス([]byte型)に変換し、逆にバイトスライスから文字列への変換も可能です。

package main

import (
    "fmt"
)

func main() {
    var s string = "こんにちは"
    var b []byte = []byte(s) // 文字列からバイトスライスへ変換
    fmt.Println(b)           // 出力: [227 129 147 227 129 147 227 129 175 227 129 168 227 129 139]

    var s2 string = string(b) // バイトスライスから文字列へ変換
    fmt.Println(s2)           // 出力: こんにちは
}


文字列と数値型の変換

文字列を数値型(例:int, float64など)に変換する例です。変換にはstrconvパッケージを使用します。

package main

import (
    "fmt"
    "strconv"
)

func main() {
    var str string = "12345"
    var num, err = strconv.Atoi(str) // 文字列をint型に変換

    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(num) // 出力: 12345
    }
}


ルーンと文字列の相互変換

ルーン(Unicodeコードポイントを表すint32型)と文字列との間の変換も一般的です。

package main

import (
    "fmt"
)

func main() {
    var r rune = 'あ'
    var s string = string(r) // ルーンから文字列へ変換
    fmt.Println(s)           // 出力: あ

    var r2 rune = rune(s[0]) // 文字列からルーンへ変換(ただしマルチバイトの場合は注意が必要)
    fmt.Println(r2)          // 出力: 'あ'のUnicodeコードポイント
}


注意点

Goでは型の互換性が厳格に管理されているため、互換性のない型間での暗黙的な変換は許されていません。これはプログラムの安全性と明確さを確保するためです。

マルチバイト文字(例えばUTF-8エンコードされた文字)を扱う場合、バイトとルーンの変換には注意が必要です。文字列のインデックス操作ではバイト単位で処理されるため、マルチバイト文字が正しく扱われないことがあります。

型変換には、値の範囲や精度の損失などのリスクが伴うことがあります。特に整数型から浮動小数点型へ、または大きいサイズの型から小さいサイズの型への変換では注意が必要です。

文字列から数値への変換では、文字列が数値として解釈可能であることを確認する必要があります。不正なフォーマットの文字列を変換しようとするとエラーが発生します。