定数の定義形式は、変数の宣言構文const name [type] = value
に似ています。次に例を示します。
const pi = 3.14159
Go では、コンパイラが値から変数の型を推測できるため、型指定子 [type] を省略できます。
- 明示的な型定義: const b string = “abc”
- 暗黙的な型定義: const b = “abc”
定数の値はコンパイル時に決定可能である必要があり、その代入式に計算プロセスが関与する可能性がありますが、計算に使用されるすべての値がコンパイル中に利用可能である必要があります。
- 良い例 const c1 = 2/3
- 良いくない例: const c2 = getNumber() // ビルド エラーが発生します: getNumber() が値として使用されます
変数宣言と同様に、複数の定数をバッチで宣言できます。
const(
e = 2.7182818、
pi = 3.1415926
)
すべての定数演算はコンパイル時に実行できるため、実行時の作業が軽減されるだけでなく、他のコードのコンパイルと最適化も容易になります。オペランドが定数の場合、整数の除算など、一部の実行時エラーがコンパイル時に見つかることもあります。ゼロ、範囲外の文字列インデックス、無効な浮動小数点数をもたらす演算など。
すべての算術演算、論理演算、および定数間の比較演算の結果も定数であり、定数に対する型変換演算または次の関数呼び出しは定数の結果を返します: len、cap、real、imag、complex、および unsafe.Sizeof。
値はコンパイル時に決定されるため、たとえば配列型の長さを指定するために、定数を型の一部にすることができます。
IPv4Len = 4
// parseIPv4はIPv4アドレス(d.d.d.d)を解析します。
func parseIPv4(s string) IP {
var p [IPv4Len]byte
// ...
}
定数宣言には型と値を含めることもできますが、型が明示的に指定されていない場合、型は右側の式から推測されます。以下のコードでは、time.Duration は名前付き型、基になる型は int64、time.Minute は対応する型の定数です。以下で宣言されている 2 つの定数は time.Duration 型であり、型情報は %T パラメーターを通じて出力できます。
const noDelay time.Duration = 0
const timeout = 5 * time.Minute
fmt.Printf("%T %[1]v\n", noDelay) // "time.Duration 0"
fmt.Printf("%T %[1]v\n", timeout) // "time.Duration 5m0s"
fmt.Printf("%T %[1]v\n", time.Minute) // "time.Duration 1m0s"
コードスニペットを翻訳します。
バッチ宣言された定数の場合、最初の定数を除く他の定数の右側の初期化式は省略できます。初期化式を省略した場合は、前の定数の初期化式が使用され、それに対応する初期化式が使用されます。定数型も同様です。例えば:
const(
a = 1
b
c = 2
d
)
fmt.Println(a、b、c、d) //「1 1 2 2」
右側の定数式を単にコピーするだけでは、あまり実用的ではありません。しかし、他の機能ももたらすことができ、それが iota 定数ジェネレーター構文です。
イオタ定数ジェネレータ
定数宣言は、iota 定数ジェネレーターを使用して初期化できます。iota 定数ジェネレーターは、同様のルールで初期化された定数のセットを生成するために使用されますが、行ごとに初期化式を記述する必要はありません。 const 宣言ステートメントでは、最初に宣言された定数が配置される行では iota が 0 に設定され、定数宣言がある行ごとに 1 ずつ増分されます。
[例 1] 最初に Weekday ネーミングタイプを定義し、次に日曜日 0 から始まる各曜日の定数を定義します。他のプログラミング言語では、この型は一般に列挙型と呼ばれます。
型 Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
日曜日は 0、月曜日は 1 などに対応します。
型なし定数
Go の定数には何か珍しい点があります。定数には、int や float64 などの明確な基礎となる型、または time.Duration などの基礎となる型を持つことができますが、多くの定数には明確な基礎となる型がありません。
コンパイラは、明確な基本型が存在しないこれらの数値定数の基本型よりも高精度の算術演算を提供します。これは、少なくとも 256 ビットの演算精度を持つと考えられます。ここには、6 つの未指定の定数タイプがあります。つまり、型なしブール、型なし整数、型なし文字、型なし浮動小数点数、型なし複素数、および型なし文字列です。
定数の具体的な型を明確にするために延期することにより、演算精度が向上するだけでなく、明示的な型変換を行わずに、より多くの式で直接使用できるようになります。
[例 2] math.Pi は型なしの浮動小数点数定数で、浮動小数点数または複素数が必要な場所で直接使用できます。
var x float32 = math.Pi
var y float64 = math.Pi
var z complex128 = math.Pi
math.Pi が float64 などの特定の型であると判断された場合、結果の精度が異なる可能性があり、float32 または complex128 型の値が必要な場合は明示的なキャストが必要です。
const Pi64 float64 = math.Pi
var x float32 = float32(Pi64)
var y float64 = Pi64
var z complex128 = complex128(Pi64)
定数リテラルの場合、異なる記述方法が異なる型に対応する場合があります。たとえば、0、0.0、0i、および \u0000 は同じ定数値を持ちますが、それぞれ、型なし整数、型なし浮動小数点数、型なし複素数、型なし文字などの異なる定数型に対応します。同様に、true と false は型なしのブール型であり、文字列リテラルは型なしの文字列型です。