基本データ型について

完了

Go は "型指定が厳密な" 言語です。 宣言したすべての変数は特定のデータ型にバインドされ、その型に一致する値のみを受け入れます。

Go では、データ型に 4 つのカテゴリがあります。

  • 基本型: 数値、文字列、ブール値
  • 集計型: 配列と構造体
  • 参照型: ポインター、スライス、マップ、関数、チャネル
  • インターフェイス型: インターフェイス

このモジュールでは基本型のみを扱います。 それ以外の型のことを知らなくても心配しないでください。 後のモジュールで解説します。

まず、数値データ型について説明します。

整数

一般的には、整数型を定義するキーワードは int です。 ただし、Go には int8int16int32int64 の各型も用意されており、これらはそれぞれ 8、16、32、64 ビットのサイズの int です。 32 ビットのオペレーティング システムを使用している場合、int のみを使用すると、サイズは通常 32 ビットになります。 64 ビットのシステムでは、int のサイズは通常 64 ビットです。 しかし、この動作はコンピューターによって異なります。 uint を使用できます。 ただし、この型は、特定の理由により値を符号なしの整数として表現する必要がある場合にのみ使用してください。 Go には uint8uint16uint32uint64 型も用意されています。

次に示すのは、Go の各種整数型の使用方法の例です。

var integer8 int8 = 127
var integer16 int16 = 32767
var integer32 int32 = 2147483647
var integer64 int64 = 9223372036854775807
fmt.Println(integer8, integer16, integer32, integer64)

ほとんどの場合、int を使用することになりますが、他の整数型についても知っておく必要があります。なぜなら、整数の自然サイズが 32 ビットの場合でも、intint32 と同じではないからです。 言い換えれば、キャストが必要なときは明示的にキャストする必要があります。 また、異なる型の間で算術演算を実行しようとすると、エラーになります。 たとえば、次のようなコードがあるとします。

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(integer16 + integer32)

プログラムを実行すると、次のエラーになります。

invalid operation: integer16 + integer32 (mismatched types int16 and int32)

ご覧のように、Go である型から別の型に値を変換する場合、新しい型を明示的に指定する必要があります。 型を正しくキャストする方法についてはこのモジュールの最後で説明します。

Go の学習を進めていく中で、rune という用語を耳にすることがあるかもしれません。 rune は単に、int32 データ型の別名です。 Unicode 文字 (または Unicode コード ポイント) を表すために使用されます。 たとえば、次のコードがあるとします。

rune := 'G'
fmt.Println(rune)

上記のコード スニペットを実行すると、プログラムによってコマンド プロンプトに G が出力される、と思われるかもしれません。 しかし、出力されるのは数値の 71 であり、これは G の Unicode 文字を表します。 rune については、後のモジュールで詳しく説明します。

Go のソース コードを見ると、それぞれの型の範囲について知ることができます。 それぞれの型の範囲を知っていれば、適切なデータ型を選択するのに役立ちますし、メモリ内のビットを無駄にすることも避けられます。

課題 1

int 型の変数をもう 1 つ設定し、integer32 または integer64 変数の値を使用して、お使いのシステムでの変数の自然サイズを確認してみましょう。 システムが 32 ビットの場合、2,147,483,647 より大きい値を使用すると、constant 9223372036854775807 overflows int のようなオーバーフロー エラーが発生します。

課題のソリューション:

package main

import "fmt"

func main() {
   var integer32 int = 2147483648
   fmt.Println(integer32)
}

課題 2

uint などの符号なし変数を宣言し、-10 のような負の値で初期化してみましょう。 プログラムを実行しようとすると、constant -10 overflows uint のようなエラーが発生するはずです。

課題のソリューション:

package main

import "fmt"

func main() {
   var integer uint = -10
   fmt.Println(integer)
}

浮動小数点数

Go には、2 つのサイズの浮動小数点数データ型 (float32float64) があります。 これらの型は、大きな数値を格納する必要があり、前述した整数型のどれにも適合しない場合に使用できます。 これらの 2 つの型の違いは、保持できる最大のビット サイズです。 これらの 2 つの型の使用方法については、次の行をご覧ください。

var float32 float32 = 2147483647
var float64 float64 = 9223372036854775807
fmt.Println(float32, float64)

これらの 2 つの型の限界は、math パッケージの math.MaxFloat32 および math.MaxFloat64 定数を使用して調べることかできます。 次のコードを使用して、最大の浮動小数点値をコマンド プロンプトに出力します。

package main

import (
    "fmt"
    "math"
)    

func main() {
    fmt.Println(math.MaxFloat32, math.MaxFloat64)
}

浮動小数点型は、10 進数値を使用する必要がある場合にも役立ちます。 たとえば、次のようなコードを記述できます。

const e = 2.71828
const Avogadro = 6.02214129e23
const Planck = 6.62606957e-34

前のコードでは、使用した値から Go によってデータ型が推定されることに注意してください。

ブール値

ブール型の可能な値は truefalse の 2 つだけです。 ブール型を宣言するには、キーワード bool を使用します。 Go は他のプログラミング言語とは異なります。 Go では、boolean 型を暗黙的に 0 か 1 のどちらかに変換することはできません。 明示的に行う必要があります。

したがって、ブール型の変数は次のように宣言できます。

var featureFlag bool = true

ブール型は、後のモジュールで Go の制御フロー ステートメントについて解説するときに使用します。 それ以降のモジュールでも使用します。

文字列

最後に、どのプログラミング言語でも最も一般的なデータ型である文字列について見てみましょう。 Go では、キーワード string を使用して文字列データ型を表します。 文字列変数を初期化するには、その値を二重引用符 (") で囲んで定義する必要があります。 単一引用符 (') は 1 つの文字に (また、前のセクションで示したように rune に) 使用します。

たとえば、次のコードは、文字列変数を宣言して初期化する 2 つの方法を示しています。

var firstName string = "John"
lastName := "Doe"
fmt.Println(firstName, lastName)

文字をエスケープすることが必要な場合もあります。 Go でこれを行うには、文字の前にバックスラッシュ (\) を使用します。 たとえば、エスケープ文字の最も一般的な使用例は次のとおりです。

  • \n 改行
  • \r 復帰
  • \t タブ
  • \' 単一引用符
  • \" 二重引用符
  • \\ バックスラッシュ

エスケープ文字をテストするには、次のコード スニペットを使用します。

fullName := "John Doe \t(alias \"Foo\")\n"
fmt.Println(fullName)

出力は次のようになります (改行を含む)。

John Doe        (alias "Foo")

既定の値

これまでは、変数を宣言するたびにほぼ毎回、値を指定して初期化してきました。 しかし Go では、他のプログラミング言語と違って、変数を初期化しない場合の既定値がすべてのデータ型にあります。 変数を使用する前に初期化済みかどうかを確認する必要がなくなるため、この機能は便利です。

これまでに見てきた型の既定値は次のとおりです。

  • 0 (int 型と、int64 などのすべてのサブタイプ)
  • +0.000000e+000 (float32 および float64 型)
  • false (bool 型)
  • 空の値 (string 型)

次のコード スニペットを実行して、上記の既定値を確認してみましょう。

var defaultInt int
var defaultFloat32 float32
var defaultFloat64 float64
var defaultBool bool
var defaultString string
fmt.Println(defaultInt, defaultFloat32, defaultFloat64, defaultBool, defaultString)

ここに挙げていないデータ型の既定値も、このようなコードを使用して確認できます。

型の変換

前のセクションで、暗黙的なキャストが Go では機能しないことを確認しました。 Go では、キャストは明示的に行う必要があります。 Go では、あるデータ型を別のデータ型に変換するためのネイティブな方法がいくつか提供されています。 たとえば、次のように、型ごとの組み込み関数を使用するのが 1 つの方法です。

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(int32(integer16) + integer32)

Go では、strconv パッケージを使用してキャストを行う別の方法もあります。 たとえば、stringint に変換する、またその逆を行うには、次のコードを使用します。

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, _ := strconv.Atoi("-42")
    s := strconv.Itoa(-42)
    fmt.Println(i, s)
}

前のコードを実行し、コードが実行されて -42 が 2 回出力されることを確認してください。

前のコードで、変数の名前としてアンダースコア (_) が使用されていることに注意してください。 Go では、_ はその変数の値を使用しないこと、また、それを無視することを意味します。 宣言したすべての変数を使用する必要があるため、このようにしないとプログラムはコンパイルされません。 このテーマについては、今後のモジュールで _ が一般的に何を表しているのかを学習します。