1 Go言語データ型の紹介

Go言語では、変数が保存できるデータの形式を決定するプログラミングの基盤であるデータ型が提供されています。Go言語で提供される基本データ型は主に次のカテゴリに分けられます。

データ型 説明 メモリ使用量
bool 真偽値を保存するためのブール型 1 バイト
int, uint 符号付きおよび符号なし整数。デフォルトのサイズは、システムプラットフォームに依存 4 または 8 バイト
int8, uint8 8 ビット符号付きおよび符号なし整数 1 バイト
int16, uint16 16 ビット符号付きおよび符号なし整数 2 バイト
int32, uint32 32 ビット符号付きおよび符号なし整数 4 バイト
int64, uint64 64 ビット符号付きおよび符号なし整数 8 バイト
float32 32 ビット浮動小数点数 4 バイト
float64 64 ビット浮動小数点数 8 バイト
complex64 32 ビット実数部と虚数部を持つ複素数 8 バイト
complex128 64 ビット実数部と虚数部を持つ複素数 16 バイト
byte uint8 に類似 1 バイト
rune int32 に類似し、Unicode のコードポイントを表す 4 バイト
string 文字列型 文字列の長さに依存
error エラー情報を返すためのエラーインタフェース サイズは固定されていない

これらの型は、数値演算、テキスト処理、論理制御など、さまざまなニーズに応じて選択できます。

2 整数データ型

2.1 整数型の概要

Go言語には複数の組み込み整数型があり、以下のように分類されます。

  • 符号付き整数: int8int16int32(または rune)、int64 および int
  • 符号なし整数: uint8(または byte)、uint16uint32uint64 および uint

int および uint のサイズは、32ビットシステムでは 4 バイト、64ビットシステムでは 8 バイトです。整数データ型の値の範囲は以下の表に示されています。

タイプ 値の範囲
int8 -128 から 127
uint8 0 から 255
int16 -32768 から 32767
uint16 0 から 65535
int32 -2147483648 から 2147483647
uint32 0 から 4294967295
int64 -9223372036854775808 から 9223372036854775807
uint64 0 から 18446744073709551615

2.2 整数型変数の使用方法

整数型の変数を宣言する基本的な構文は次のようになります:

var 変数名 データ型 = 初期値

サンプルコード:

package main
import "fmt"

func main() {
    var a int = 10 // 符号付き整数の変数
    var b uint = 20 // 符号なし整数の変数
    var c int8 = -128 // 最小の int8 値
    fmt.Println(a, b, c)
}

2.3 整数演算

Go言語は、加算(+)、減算(-)、乗算(*)、除算(/)、剰余(%)などの一般的な算術演算子およびビット演算子(ビットごとのAND(&)、OR(|)、XOR(^)、左シフト(<<)、右シフト(>>)など)をサポートしています。

package main
import "fmt"

func main() {
    x := 10
    y := 3

    // 算術演算
    fmt.Println(x + y) // 加算
    fmt.Println(x - y) // 減算
    fmt.Println(x * y) // 乗算
    fmt.Println(x / y) // 除算
    fmt.Println(x % y) // 剰余

    // ビット演算
    fmt.Println(x & y)  // ビットごとのAND
    fmt.Println(x | y)  // ビットごとのOR
    fmt.Println(x ^ y)  // ビットごとのXOR
    fmt.Println(x << 1) // 1ビット左シフト
    fmt.Println(x >> 1) // 1ビット右シフト
}

3 浮動小数点型データ

3.1 浮動小数点データ型の概要

Go言語では、浮動小数点型にはfloat32float64があり、それぞれ32ビットと64ビットの浮動小数点データに対応しています。一般的に、より広い範囲とより正確な精度を提供するため、float64の使用を推奨します。

  • float32はおおよそ23ビットの有効桁を持ち、約7桁の10進数の精度を提供します。
  • float64はおおよそ52ビットの有効桁を持ち、約16桁の10進数の精度を提供します。

3.2 浮動小数点変数の使用

浮動小数点変数は、リテラルを直接指定するか、varキーワードを使用して宣言することができます。

package main
import "fmt"

func main() {
    var f1 float32 = 3.14 // float32型を明示的に指定
    f2 := 3.14           // 自動的にfloat64型と推論される
    fmt.Println(f1, f2)
}

3.3 浮動小数点演算と問題

浮動小数点演算は精度の損失を引き起こすことがあります。非常に高い精度で操作を行う場合、特に非常に近い数値を引き算するときに一般的な問題です。

package main
import "fmt"

func main() {
    f1 := .1
    f2 := .2
    f3 := f1 + f2
    fmt.Println(f3) // 精度の問題により、期待通りの.3とはならないことがあります

    // フォーマットされた出力を使用して精度の問題を修正する
    fmt.Printf("%.1f\n", f3) // 出力を.3に修正
}

4 真偽値データ型

4.1 真偽値データ型の概要

ブーリアンは最も単純なデータ型であり、true(真)とfalse(偽)の2つの値しか取ることができません。条件文やループ制御構造において非常に重要な位置を占めています。

4.2 真偽値変数の使用

ブーリアン変数の宣言と使用方法:

package main
import "fmt"

func main() {
    var success bool = true
    var fail bool = false
    fmt.Println("操作は成功しました:", success)
    fmt.Println("操作は失敗しました:", fail)
}

ブーリアン値は条件文でよく使用されます:

package main
import "fmt"

func main() {
    a := 10
    b := 20
    fmt.Println("a == b:", a == b) // false
    fmt.Println("a < b:", a < b)   // true
}

5 文字列データ型

5.1 文字列概要

文字列は文字の集まりです。Go言語では、文字列は不変です。各文字列は、基になるバイト配列へのポインタと長さで構成されています。文字列にはバイトを含む任意のデータを入れることができます。

5.2 文字列変数の使用

文字列変数は一般的にダブルクォーテーション"を使用して宣言されますが、複数行の文字列を作成する場合はバッククォート`を使用することもできます。

package main
import "fmt"

func main() {
    var s1 string = "hello"
    s2 := "world"
    s3 := `これは
    複数行の
    文字列です`
    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println(s3)
}

文字列が作成された後は、その内容を変更することはできません。以下の操作は違法であり、コンパイルエラーを引き起こします。

s := "hello"
s[] = 'H` // コンパイルエラー: 文字列の内容は不変です

5.3 文字列の操作

文字列はプログラミングで非常に一般的で重要です。Go言語では、文字列の操作のための豊富な組み込み関数が提供されています。以下はいくつかよく使用される操作です。

5.3.1 文字列の連結

Go言語では、文字列を連結するにはプラス記号(+)演算子を使用することができます。また、複数の文字列を頻繁に連結する場合は、パフォーマンスのためにstrings.Builderを使用することを推奨します。

package main

import (
    "fmt"
    "strings"
)

func main() {
    // + を使用した文字列の連結
    hello := "Hello, "
    world := "World!"
    result := hello + world
    fmt.Println(result) // 出力: Hello, World!

    // strings.Builderを使用した文字列の連結
    var sb strings.Builder
    sb.WriteString("Hello, ")
    sb.WriteString("World!")
    fmt.Println(sb.String()) // 出力: Hello, World!
}

5.3.2 文字列の分割

文字列の分割は、指定された区切り文字に基づいて文字列をスライスに分割する strings.Split 関数を使用して行うことができます。

package main

import (
    "fmt"
    "strings"
)

func main() {
    // 文字列を定義する
    sentence := "Goはオープンソースのプログラミング言語です"

    // スペースで文字列を分割する
    words := strings.Split(sentence, " ")
    for _, word := range words {
        fmt.Printf("%s\n", word)
    }
    // 出力:
    // Go
    // はオープンソースのプログラミング言語です
}

5.3.3 インデックスアクセス

Go言語では、文字列はバイトの不変のシーケンスです。文字列内の特定のバイトにアクセスするためにインデックスを使用することができます。ただし、UTF-8でエンコードされた文字など、マルチバイト文字が含まれる場合、直接インデックスを使用すると期待される単一の文字が得られないことに注意することが重要です。

package main

import "fmt"

func main() {
    s := "Hello, 世界"
    for i := range s {
        fmt.Printf("%d: %x\n", i, s[i])
    }
    // 注意: これは文字の代わりにバイトの16進数表現を出力します
}

文字列を文字単位で反復処理するには、range ループを使用することができます。

package main

import "fmt"

func main() {
    s := "Hello, 世界"
    for index, runeValue := range s {
        fmt.Printf("%d: %U '%c'\n", index, runeValue, runeValue)
    }
    // 出力: 各文字について、インデックス、Unicodeエンコーディング、および文字自体を出力
}

5.3.4 長さの取得

len 関数は、文字列の長さ、つまり基になるバイトシーケンスの長さを取得できます。UTF-8文字列では、文字数(ルーン)を取得する場合は utf8.RuneCountInString 関数を使用する必要があります。これにより、マルチバイト文字が正しく処理されます。

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    s := "Hello, 世界"
    fmt.Println("バイト長:", len(s)) // バイト長を出力
    fmt.Println("ルーン長:", utf8.RuneCountInString(s)) // 文字長を出力
}

上記の例からわかるように、Go言語は文字列操作のための豊富なライブラリ関数を提供しており、さまざまな文字列処理のタスクを簡単に実行できます。コーディングする際には、特に非ASCII文字セットを扱う場合は、バイトと文字の区別に注意することが重要です。