Go 言語入門基礎学習ノートの Go 言語の定数
定数#
定数定義#
定数はプログラム実行時に変更されない単純な値の識別子です。
定数のデータ型はブール型、数値型(整数型、浮動小数点型、複素数)および文字列型のみです。
定数の定義形式:
const identifier [type] = value
同様に、ここでは型指定子 type
を省略することができ、コンパイラは定数の値に基づいて自動的に型を推論します。これにより、明示的型定義と暗黙的型定義に分かれます。
同じ型の複数の宣言は次のように短縮できます:
const c_name1, c_name2 = value1, value2
定数は列挙型の定義にも使用できます:
const (
Unknown = 0
Female = 1
Male = 2
)
列挙型が多い場合、一つずつ値を割り当てるのは非常に面倒なので、Go 言語はキーワードiotaを提供しています。
定数は len()
, cap()
, unsafe.Sizeof()
関数を使用して式の値を計算できます。定数式内では、関数は組み込み関数でなければならず、そうでないとコンパイルは通りません。
package main
import "unsafe"
const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(a)
)
func main(){
println(a, b, c)
}
// 出力結果
abc 3 16
補足:
unsafe.Sizeof(a)
は a の型がメモリ内で占めるバイト数を返します。文字列型の場合、unsafe.Sizeof()
は文字列の内容のサイズではなく、文字列の内部構造へのポインタのサイズを返します。
Go では、文字列は 2 つのフィールドを持つ構造体です:
- ポインタ:文字列内容のメモリアドレスを指します。
- 長さ:文字列内容の長さ(バイト単位)を示します。
文字列型の構造体は通常 16 バイトを占めます(64 ビットシステムの場合)。具体的には:
- ポインタ:8 バイト(64 ビットシステムの場合)
- 長さ:8 バイト(64 ビットシステムの場合)
したがって、文字列の総サイズは 8 + 8 = 16 バイトです。
iota#
iota は特殊な定数であり、コンパイラによって変更可能な定数と見なすことができ、const
内でのみ使用できます。定数宣言内で関連する定数値の系列を生成するために使用できます。
iota は const キーワードが出現する際に 0 にリセットされます(const 内部の最初の行の前)。const 内で新しい定数宣言が追加されるたびに iota は 1 回カウントされます(iota は const 文ブロック内の行インデックスと理解できます)、つまり iota=行数-1
です。
iota は列挙値として使用できます:
const (
a = iota // 0
b = iota // 1
c = iota // 2
)
最初の iota は 0 に等しく、新しい行で iota が使用されるたびにその値は自動的に 1 加算されます。したがって、a=0, b=1, c=2 は次のように短縮できます:
const (
a = iota
b
c
)
注意:iota
は行ごとに増加するため、同じ行であればiota
は同じです。また、次のiota
の式は上の最近の式と一致する必要があります。例えば:
const (
a, b = iota + 1, iota + 2 // iota=0 a=1 b=2
c, d // iota=1 c=iota+1 d=iota+2
e, f = iota * 2, iota * 3 // iota=2 e=4 f=6
g, h // iota=3 g=iota*2 f=iota*3
)
iota の使い方
package main
import "fmt"
func main() {
const (
a = iota //0
b //1
c //2
d = "ha" //独立値、iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,カウントをリセット
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
// 出力結果
0 1 2 ha ha 100 100 7 8
Go では、定数宣言内の連続する未明示的な値の定数は前の定数の値を取ります。e
は明示的に値を割り当てられていないため、前の定数d
の値(つまり"ha"
)を継承します。同様に、g
も明示的に値を割り当てられていないため、前の定数f
の値(つまり100
)を継承します。
package main
import "fmt"
const (
i=1<<iota
j=3<<iota
k
l
)
func main() {
fmt.Println("i=",i)
fmt.Println("j=",j)
fmt.Println("k=",k)
fmt.Println("l=",l)
}
// 出力結果
i= 1
j= 6
k= 12
l= 24
上記の例では、iota は 0 から自動的に 1 ずつ加算されるため、i=1<<0
、j=3<<1
(<<
は左シフトを意味し、<<n==*(2^n)
)となり、したがってi=1
、j=6
、k=12
、l=24
となります。
- i=1:0 ビット左シフト、変わらず 1。
- j=3:1 ビット左シフト、2 進数110となり、6。
- k=3:2 ビット左シフト、2 進数1100となり、12。
- l=3:3 ビット左シフト、2 進数11000となり、24。
参考コース: