2章 事前宣言された型
from 初めてのGo言語 第2版 ―他言語プログラマーのためのイディオマティックGo実践ガイド
事前宣言された型(predeclared type)= 組み込み型
整数・浮動小数点数 リテラル
0 から始まる数字は 8 進数
16 進数 に p を付けると、累乗 を表現できる(e.g. 0x12.34p5 = 582.5)
デフォルトの型は整数が int、浮動小数点数が float64
rune リテラル
表現方法
1 文字の Unicode 文字: 'a'
8 bit 8 進数: \141
8 bit 16 進数: \x61
16 bit 16 進数: \u0061
32 bit Unicode: \U00000061
デフォルトの型は rune
文字列リテラル
表現方法
解釈対象の文字列リテラル(interpreted string literal)
" で囲う通常の文字列
\n は改行として「解釈」される
ロー文字リテラル(raw string literal)
` で囲う文字列
` 以外の文字をそのまま記述できる
デフォルトの型は string
特別な整数型
byte: uint8 の エイリアス
rune: 1 つの コードポイント を表現する、int32 のエイリアス
uintptr: C のような ポインタ 操作を可能とする
どの整数型を選択すべきか
特定の大きさと 符号 の整数 バイナリ のファイル、ネットワークプロトコルを処理する: 対応する整数型を用いる
すべての整数型で機能するユーティリティ関数を実装する: ジェネリクス を利用する
上記以外: int を利用する
Go の 整数演算は 無検査変換 を行わない
初めて知った… radish-miyazaki.icon
そのため、以下のコードは panic を起こさず、ラップアラウンド する
code:go
var b byte = 255
var smallI int32 = 2147483647
var bigI uint64 = 18446744073709551615
fmt.Println(b+1, smallI+1, bigI+1) // 0 -2147483648 0
じゃあどう検出するのか radish-miyazaki.icon
math/bits 使えばいけそう?
code:go
sum, carry := bits.Add32(4294967295, 1, 0)
if carry == 1 {
fmt.Println("Overflow!")
}
複素数の型
ゼロ値 は 0
実部 と 虚部 を表すのに float32 を用いる complex64、float64 を用いる complex128 とがある
リテラルは 1+2i のように記述できる
デフォルトの型は complex128
実部の値を取り出すには real、虚部の値を取り出すには imag を用いる
文字型・文字列型
Go の文字列は イミュータブル であるため、変数に代入された文字列値を変えることはできない
再代入は可能
型変換
Go は変数間の 暗黙的な型変換は行わない
整数や浮動小数点数でサイズが異なる場合も変換が必要
code:go
var x int = 10
var y float64 = 30.2
var sum1 float64 = float64(x) - y
var sum2 int = x + int(y)
warning.icon 整数・浮動小数点数リテラル間で演算することは可能
∵ Go のリテラルは型付けされていない(untyped)ため
code:go
var x float64 = 200.3 * 5
ただし、文字列リテラルの数値型変数への代入や、サイズなど制限はある
bool 以外の変数を bool として扱うことも不可
:= による変数宣言を避けるべきケース
ゼロ値で初期化したい
デフォルトの型が希望する型と異なる
変数宣言と再代入が混在している
code:go
x := 10
x, y := 30, "hello"
どの変数が新しいものかを明示するために var を使って新しい変数を明示的に宣言し、= で代入する
定数
定数の宣言はパッケージレベルのみ
Go の定数はリテラルに名前を付ける(コンパイル時に決定できる値を保持する)だけなので、以下のみ代入できる
数値リテラル
true、false
文字列
rune
complex、real、imag、len、cap 関数の結果
上記の値と演算子からなる式
定数も変数と同じように型付けは任意
型がない場合はデフォルト型が用いられる
変数とは異なり、定数は使われなくてもコンパイルエラーにならない
∵ 定数はコンパイル時に計算され、副作用 がないため
定数が使われていなければコンパイル後のバイナルファイルに含める必要がなくなるだけ
パッケージレベルの変数も同様にコンパイルエラーにならない
定数名は Xxx、xxx が一般的(XXX_XXX ではない)
Go では実行時に計算された値がイミュータブルであることを指定する方法はない
そのため、イミュータブルな配列やスライス、マップ、構造体は存在しない
構造体のフィールドがイミュータブルであることを宣言する方法もない
#読書メモ #Go