覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Go言語 - 整数型

Go言語では整数を扱うための型が複数提供されています。
以下は、各整数型の違いなどについてのメモとなります。


実装系に依存しない整数型

以下の整数型は実装系によらずサイズが決まっています

サイズ(bit) 符号 最小値 最大値
int8 8 あり -128 127
int16 16 あり -32768 32767
int32 32 あり -2147483648 2147483647
int64 64 あり -9223372036854775808 9223372036854775807
uint8(byte) 8 なし 0 255
uint16 16 なし 0 65535
uint32 32 なし 0 4294967295
uint64 64 なし 0 18446744073709551615

uint8の別名としてbyte型が定義されています。1バイト単位を表現するような処理の記述にはbyte型の方が向いているかもしれないです


mathパッケージのmath.MinXXXmath.MaxXXXの定数で各型で扱うことのできる最小値、最大値を確認できます。

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Printf("int8   -> min:%d, max:%d\n", math.MinInt8, math.MaxInt8)
    fmt.Printf("int16  -> min:%d, max:%d\n", math.MinInt16, math.MaxInt16)
    fmt.Printf("int32  -> min:%d, max:%d\n", math.MinInt32, math.MaxInt32)
    fmt.Printf("int64  -> min:%d, max:%d\n", int64(math.MinInt64), int64(math.MaxInt64))

    fmt.Printf("uint8  -> min:0, max:%d\n", math.MaxUint8)          // uint8の最小値は0。最小値の定数は無い
    fmt.Printf("uint16 -> min:0, max:%d\n", math.MaxUint16)         // uint16の最小値は0。最小値の定数は無い
    fmt.Printf("uint32 -> min:0, max:%d\n", uint32(math.MaxUint32)) // uint32の最小値は0。最小値の定数は無い
    fmt.Printf("uint64 -> min:0, max:%d\n", uint64(math.MaxUint64)) // uint64の最小値は0。最小値の定数は無い
}

■実行結果

int8   -> min:-128, max:127
int16  -> min:-32768, max:32767
int32  -> min:-2147483648, max:2147483647
int64  -> min:-9223372036854775808, max:9223372036854775807
uint8  -> min:0, max:255
uint16 -> min:0, max:65535
uint32 -> min:0, max:4294967295
uint64 -> min:0, max:18446744073709551615


実装系依存の整数型

Go言語はサイズがきっちり決まった整数型だけではなく、OSやCPUなどの実装系に依存した(実装系によってサイズが変わる)整数型も存在しています。
(C言語におけるintに似たような感じです)

サイズ(32bit実装) サイズ(64bit実装) 符号
int 32bit 64bit あり
uint 32bit 64bit なし
uintptr なし

※uintprtは ポインタの値をそのまま格納するために十分な大きさの符号なし整数


変数宣言した値の各型の確認

整数リテラル含めた各型の値を変数宣言して、実際に変数の型がどうなっているかを確認してみます。

先に書きますが、整数リテラルを使って暗黙的に定義した変数はint型になります

■サンプルコード

package main

import "fmt"

func main() {
    val1 := 123
    fmt.Printf("val1 -> %d, type: %T\n", val1, val1)

    val2 := int(123)
    fmt.Printf("val2 -> %d, type: %T\n", val2, val2)

    val3 := uint(123)
    fmt.Printf("val3 -> %d, type: %T\n", val3, val3)

    val4 := int16(123)
    fmt.Printf("val4 -> %d, type: %T\n", val4, val4)

    val5 := int32(123)
    fmt.Printf("val5 -> %d, type: %T\n", val5, val5)

    val6 := int64(123)
    fmt.Printf("val6 -> %d, type: %T\n", val6, val6)
}

■実行結果

val1 -> 123, type: int
val2 -> 123, type: int
val3 -> 123, type: uint
val4 -> 123, type: int16
val5 -> 123, type: int32
val6 -> 123, type: int64

整数リテラルで宣言した変数(val1)の型がintになっていることが分かります