Menu

Go言語のデータ型:int、float64、string、bool、byte、rune

Goの組み込み型を解説します。整数のサイズと範囲、float32とfloat64、bool、string、byteとrune、複素数、ゼロ値、そして%Tで値の型を表示する方法まで。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

Goの基本型は、数値、真偽値、文字列です。どの変数もコンパイル時に決まるちょうど1つの型を持ち、Goが型を勝手に変換することはありません。%T はどんな値の型でも表示します。

'G' が型 int3271 として表示されることに注目してください。シングルクォートで囲んだ文字はルーンで、ルーンは数値(Unicodeのコードポイント)です。runeint32 の別名(同じ型に付けた2つ目の名前)なので、%Tint32 と表示します。同じように byteuint8 と表示されます。

整数

サイズ範囲
int88ビット-128から127
int1616ビット-32,768から32,767
int3232ビット約-21億から21億
int6464ビット約-922京から922京
uint8byte8ビット0から255
uint1616ビット0から65,535
uint3232ビット0から約43億
uint6464ビット0から約1844京
intuint32または64ビットプラットフォームのワードサイズ
uintptrプラットフォーム依存低レベルのコード向けに、ポインタの値を保持する

デフォルトでは int を使います。 len()int を返し、スライスのインデックスも int、ループのカウンタも int です。64ビットのプラットフォームではどこでも int は64ビットです。サイズ付きの型を使うのは、サイズが取り決めの一部になっているときです。バイナリファイル形式の int32、生のバイトの uint8、ナノ秒単位のUnixタイムスタンプの int64 などです。

個数のように「負にならない」量に符号なし型を使うのは避けましょう。ゼロより下に引き算すると、検出できる負の数になるのではなく、巨大な数に折り返します。

上限とオーバーフロー

math パッケージには、すべての上限に対応する定数があります。実行時に整数の演算がオーバーフローすると、何も言わずに折り返します。

panicもエラーもなく、127 + 1-128 になります。コンパイル時にチェックされるのは定数式だけです(var b int8 = 128 はコンパイルできません)。データでオーバーフローが起こりうるなら、演算の前にチェックするか math/big を使います。

整数リテラル

million := 1_000_000   // underscores for readability (Go 1.13+)
mask := 0xFF           // hexadecimal
perm := 0o755          // octal (also the older form 0755)
flags := 0b1010        // binary

浮動小数点数

サイズ精度
float3232ビット有効桁数 約6から9桁
float6464ビット有効桁数 約15から17桁

小数点や指数を含むリテラル(2.51e6)はデフォルトで float64 になり、math パッケージも float64 を受け取って返します。大きな配列でメモリが問題にならない限り、これを使います。

浮動小数点数は2進数なので、ほとんどの10進の小数は近似値になります。

ここから2つのルールが導かれます。演算した後の浮動小数点数を == で比較してはいけません。そして、お金を浮動小数点数で保存してはいけません。セント単位の整数か、10進数のライブラリを使います。

浮動小数点数をゼロで割ると、panicせずに +Inf-InfNaN になります。整数 をゼロで割ると実行時にpanicし(runtime error: integer divide by zero)、定数のゼロで割るとコンパイルエラーになります。

真偽値

booltruefalse を保持し、ゼロ値は false です。Goは数値、空文字列、nil を真偽値として扱いません。if count {} はコンパイルエラーで、if count > 0 {} と書きます。演算子は &&||! で、&&|| は短絡評価されます。

文字列

string は変更できないバイトの並びで、通常はUTF-8のテキストです。len(s) は文字数ではなくバイト数を数えます。

é はUTF-8で2バイトを使うので、5文字に対して len は6を返します。ダブルクォートの文字列は \n のようなエスケープを処理しますが、バッククォートの生文字列は処理せず、複数行にまたがれます。strings パッケージは文字列のページで、UTF-8の詳細はルーンとバイトのページで扱っています。

byteとrune

別名実体保持するもの
byteuint8生データの1バイト
runeint32Unicodeのコードポイント1つ

これらは新しい型ではなく別名です。byteuint8 は変換なしで相互に使えます。名前は、その数値が何を意味するかを表しています。

複素数

Goには組み込みの複素数型 complex64complex128 があり、realimag、そして math/cmplx パッケージで扱います。

必要とするプログラムは多くありませんが、信号処理や一部の数値計算のコードでは使われます。

複合型と参照型

基本型を組み合わせると複合型になります。それぞれに専用のページがあります。

ゼロ値
配列[3]int3つのゼロ
スライス[]intnil
マップmap[string]intnil
構造体struct{ X, Y int }すべてのフィールドがゼロ値
ポインタ*intnil
関数func(int) intnil
チャネルchan intnil
インターフェースerroranynil

anyinterface{} の別名で(Go 1.18以降)、どんな型の値でも保持できます。

名前付きの型

既存の型から新しい型を定義できます。表現は同じですが別の型であり、メソッドを持てます。

type Celsius float64
type UserID int64

var t Celsius = 21.5
var f float64 = t // compile error: cannot use t (variable of float64 type Celsius) as float64 value in variable declaration

この厳しさこそが狙いです。OrderID が必要な場所に、うっかり UserID を渡すことはできません。意図しているときは明示的に変換します:float64(t)。ルールは型変換のページを、数値と文字列の相互変換は strconv の関数を参照してください。

ゼロ値

どの型にもゼロ値があり、何も代入する前の変数はそれを保持しています。数値は 0boolfalse、文字列は ""、ポインタ、スライス、マップ、チャネル、関数、インターフェースは nil です。Goに初期化されていない変数はありません。

よくある質問

Goのintは何ビットですか?

intuint は、64ビットのプラットフォーム(amd64、arm64)では64ビット、32ビットのプラットフォームでは32ビットです。ファイル形式やネットワークプロトコルなどで固定のサイズが必要なら、int32int64uint8 などを使います。普通のカウンタ、インデックス、長さには int を使います。

Goで変数の型を表示するには?

%T 書式指定子を使います:fmt.Printf("%T\n", x)intfloat64[]stringmain.User などを表示します。コードの中では、reflect.TypeOf(x) が同じ情報を調べられる値として返します。

Goのbyteとruneの違いは何ですか?

byteuint8 の別名で、生データの1バイトを保持します。runeint32 の別名で、Unicodeのコードポイント1つを保持します。文字列はバイトの並びで、for range で走査するとルーンにデコードされます。

Goではfloat32とfloat64のどちらを使うべきですか?

理由がない限り float64 を使います。浮動小数点数リテラルのデフォルトの型であり、math パッケージが扱う型であり、有効桁数は10進で約15から17桁あります(float32 は約6から9桁)。float32 を選ぶのは、大きな配列でメモリを半分にしたいときか、外部の形式に合わせるときだけです。

Goのintの最大値はいくつですか?

math パッケージの定数を使います:math.MaxInt(64ビットのプラットフォームでは9223372036854775807)、math.MinIntmath.MaxInt64math.MaxUint32 などです。上限を超える演算は実行時に何も言わずに折り返し、panicはしません。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める