Go/キーワードと宣言済み識別子

< Go

キーワードと宣言済み識別子

編集

Goでは、他の言語でキーワードや予約語と呼ばれる構文要素が、キーワード(Keywords)と宣言済み識別子(Predeclared identifiers)に別れます。

キーワード

編集

以下のキーワードは予約済みで、識別子として使用することはできません[1]

Goのキーワード一覧
break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type 
continue     for          import       return       var

intfloat32 などのプリミティブな型名が含まれていませんが、それらは宣言済み識別子です。 このため、var int = 123.456は、float64型の変数 int 値は 123.456 と「正しく」解釈されます。 PL/Iのようですね。

宣言済み識別子

編集

ユニバースブロック(universe block[2])では、以下の識別子が暗黙的に宣言されています[3]。これらの識別子は、Goのすべてのスコープで暗黙的に利用可能であり、特定の目的で使用されます。

型 (Types):

編集

以下のが宣言済みです:

定数 (Constants):

編集

以下の定数が事前定義されています:

  • true, false: 真偽値。
  • iota: 定数宣言のカウンタとして使用される識別子。

ゼロ値 (Zero value):

編集

以下のゼロ値が事前定義されています:

  • nil: ポインタ、スライス、マップ、チャネル、関数、またはインターフェースのゼロ値。

関数 (Functions):

編集

以下の関数が事前定義されています:

  • append: スライスに要素を追加します。
  • cap: スライスやチャネルの容量を返します。
  • clear: マップやスライスの内容をクリアします。
  • close: チャネルを閉じます。
  • complex: 実部と虚部から複素数を作成します。
  • copy: スライス間の要素をコピーします。
  • delete: マップからキーを削除します。
  • imag: 複素数の虚部を返します。
  • len: 配列、スライス、文字列、マップ、またはチャネルの長さを返します。
  • make: スライス、マップ、またはチャネルを作成します。
  • max, min: ジェネリクスで使用可能な最大値・最小値を返す関数(Go 1.21以降)。
  • new: 指定された型のゼロ値を持つポインタを作成します。
  • panic: 実行を停止し、パニックを発生させます。
  • print, println: デバッグ用に値を出力します(通常は避けるべき)。
  • real: 複素数の実部を返します。
  • recover: パニック状態を回復します。

解説

編集

これらの宣言済み識別子は、Goプログラムを簡潔に書くための基盤を提供します。たとえば、以下のような用途があります:

  1. 型(Types):
    • プリミティブ型(int, float64 など)は、基本的なデータの表現に使用されます。
    • anycomparable は、ジェネリクス(1.18以降)の制約として便利です。
  2. 定数(Constants):
    • truefalse は条件式で使用されます。
    • iota は列挙型のような定数リストの定義に便利です。
  3. ゼロ値(Zero value):
    • nil は、初期化されていないポインタやスライスなどに使用されます。
  4. 関数(Functions):
    • appendcopy はスライス操作を簡潔にします。
    • lencap は、データ構造の情報を取得するのに役立ちます。
    • panicrecover はエラー処理の仕組みとして重要です。

これらの識別子は、Goでプログラムを書く際の基本的なビルディングブロックとして機能します。特に ジェネリクス(Go 1.18以降) の登場によって、新しい識別子(any, comparable, max, min)が追加され、より柔軟なコードが書けるようになりました。

Goでは、いくつもの型をあらかじめ宣言しています[4]。 規格では特にこの様な型のグループに呼び名を与えていませんが、本書でが便宜上名前が必要なので、宣言済み識別子を持つ関数を組込み関数(built-in function[5])と呼ぶのにならって、宣言済み識別子を持つ型を組込み型と呼びます。

論理型

編集

組込み型 bool は論理型(boolean type) です。 論理型は事前に宣言された定数 truefalse で示される論理真理値の集合を表します。組込み型です[6]

数値型

編集

整数型、浮動小数点型、複素数型は、それぞれ整数値、浮動小数点値、複素数値の集合を表します。これらは総称して数値型(numeric type)と呼ばれます。事前に宣言されているアーキテクチャに依存しない数値型は次のとおりです[7]

符号なし整数
uint8
すべての符号なし8ビット整数(0~255)の集合
uint16
すべての符号なし16ビット整数(0~65535)の集合
uint32
すべての符号なし32ビット整数(0~4294967295)の集合
uint64
すべての符号なし64ビット整数(0~18446744073709551615)の集合
符号付き整数
int8
すべての符号付き8ビット整数(-128~127)の集合
int16
すべての符号付き8ビット整数(-32768 ~32767)の集合
int32
すべての符号付き8ビット整数(-2147483648 ~2147483647)の集合
int64
すべての符号付き8ビット整数(-9223372036854775808 ~9223372036854775807)の集合
浮動小数点数
float32
IEEE-754の32ビット浮動小数点数の集合
float64
IEEE-754の64ビット浮動小数点数の集合
複素数
complex64
float32の実数部と虚数部を持つすべての複素数の集合
complex128
float64mappuの実数部と虚数部を持つすべての複素数の集合
別名
byte
uint8の別名
rune
int32の別名

また、実装固有のサイズを持つ宣言済みの数値型のセットもあります。

uint
32ビットまたは64ビット
int
uintと同じサイズ
uintptr
ポインタ値のビットを解釈不要で格納するのに十分な大きさの符号なし整数

文字列型

編集

組込み型 string は、文字列型(string type) です[8]。 文字列型は、文字列値(string values)の集合を表します。文字列の値は、(空の場合もある)バイトの列です。バイトの数は文字列の長さと呼ばれ、負の値にはなりません。文字列は不変(immutable)です。一度作成した文字列の内容を変更することはできません。

文字列 s の長さは,組み込み関数 len を使って知ることができます。文字列が定数の場合,長さはコンパイル時の定数となります。文字列のバイトは,0からlen(s)-1までの整数の添字でアクセスできます。 要素のアドレスを取ることは違法です。s[i]が文字列のi番目のバイトである場合、&s[i]は無効です。

エラー

編集

組込み型 error は次のように定義されています[9]

type error interface {
	Error() string
}

これは、エラー状態を表現するための従来のインターフェースで、nil値はエラーがないことを表します。例えば、ファイルからデータを読み込む関数が定義されているとします。

func Read(f *File, b []byte) (n int, err error)

組込み関数

編集

組込み関数はあらかじめ宣言されています。これらは他の関数と同様に呼び出されますが、中には最初の引数として式ではなく型を受け取るものもあります[5]。 組込み関数は、Goの標準的な型を持たないので、呼び出し式の中でのみ登場し、関数の値としては使えません。

クローズ

編集

チャンネルcに対して、組込み関数close(c)は、そのチャンネルでそれ以上の値が送信されないことを記録します[10]。 cが受信専用のチャンネルの場合はエラーになります。 閉じたチャネルに送信したり、閉じたりすると、ランタイム・パニック(run-time panic)を起こします。 nilチャンネルのクローズもランタイム・パニックを引き起こします。 closeを呼び出した後、それまでに送信された値がすべて受信された後、受信操作はブロックすることなくチャネルのタイプに応じたゼロの値を返します。 多値受信操作(multi-valued receive operation)では、チャネルが閉じているかどうかの表示とともに、受信値が返されます。

長さと容量

編集

組込み関数 lencap は、様々な型の引数を取り、int型の結果を返します。実装では、結果が常にint型に収まることが保証されています[11]

長さと容量
呼び出し 引数の型 戻り値
len(s) string type 文字列の長さ(バイト)
[n]T, *[n]T 配列の長さ (== n)
[]T スライスの長さ
map[K]T mapの長さ (定義されたキーの数)
chan T チャンネルバッファにキューイングされている要素の数
cap(s) [n]T, *[n]T 配列の長さ (== n)
[]T スライスの容量
chan T チャンネルバッファの容量

スライスの容量は、基礎となる配列に割り当てられたスペースがある要素の数です。いつでも以下の関係が成り立ちます。

0 <= len(s) <= cap(s)

nilのスライス、マップ、チャンネルの長さは0です。nilのスライス、チャンネルの容量は0です。

式 len(s) は、s が文字列定数の場合、定数です。式 len(s) と cap(s) は、s の型が配列または配列へのポインタで、式 s にチャンネルの受信や (定数でない) 関数呼び出しが含まれていない場合、定数となり、この場合 s は評価されません。この場合,s は評価されません。そうでなければ,len と cap の呼び出しは定数ではなく,s は評価されます。

割当て

編集

組込み関数 new は,型Tを受け取り,実行時にその型の変数のためのストレージを確保し,その変数を指す*T型の値を返します。この変数は,初期値の項で説明したように初期化されます[12]

new(T)

例えば

type S struct { a int; b float64 }
new(S)

S型の変数の格納場所を確保して初期化し(a=0, b=0.0),その場所のアドレスを含む*S型の値を返すようになっています。

スライス、マップ、チャンネルの作成

編集

組込み関数 make は,スライス型,マップ型,チャネル型でなければならないT型を受け取り,任意で型固有の式のリストを続けます。 この関数は,T型の値を返します(*Tではありません)。 メモリは,初期値の項で述べたように初期化されます。[13]

スライス、マップ、チャンネルの作成
呼び出し 引数の型T 戻り値
make(T, n) slice 長さn、容量nのタイプTのスライス
make(T, n, m) slice 長さn、容量mのタイプTのスライス
make(T) map 型Tのマップ
make(T, n) map 約n個の要素の初期空間を持つ型Tのマップ
make(T) channel 型Tのバッファなしチャネル
make(T, n) channel 型Tのバッファサイズnのバッファ付きチャネル、

サイズ引数nとmは、それぞれ整数型または型付けされていない定数でなければなりません。定数のサイズ引数は非負で、int型の値で表されなければなりません。型付けされていない定数の場合、int型が与えられます。nとmの両方が提供され、かつ定数である場合、nはmより大きくてはなりません。実行時にnが負またはmより大きい場合、実行時パニックが発生します。

スライスの追加とコピー

編集

組込み関数 appendcopy は、一般的なスライス操作を支援します。どちらの関数も、引数で参照されるメモリが重なっているかどうかに関係なく、結果が得られます[14]

可変長引数(variadic)な関数appendは、0個以上の値xをスライス型でなければならないS型のsに追加し、結果としてS型のスライスを返します。値xは、TがSの要素型である...T型のパラメータに渡され、それぞれのパラメータ通過規則が適用されます。特殊なケースとして、appendは、[]byte型に割り当てられる第1引数と、... に続く文字列型の第2引数も受け入れます。この形式では、文字列のバイトを追加します。

append(s S, x ...T) S  // T は S の要素の型

sの容量が追加の値を収めるのに十分な大きさでない場合、appendは既存のスライス要素と追加の値の両方を収めることができる、十分に大きい新しい基本配列を割り当てます。そうでなければ、appendは基礎となる配列を再利用します。

マップ要素の削除

編集

組込み関数 delete は,キーkを持つ要素をマップmから削除します。kの型はmのキーの型に割り当て可能でなければなりません[15]

delete(m, k)  // マップmから要素m[k]を削除

マップmがnilであったり、要素m[k]が存在しない場合、deleteはno-opとなります。

複素数の操作

編集

3つの関数が複素数を組み立てたり分解したりします。組込み関数 complex は,浮動小数点の実部と虚部から複素数値を構成し,realimag は複素数値の実部と虚部を抽出します[16]

complex(realPart, imaginaryPart floatT) complexT
real(complexT) floatT
imag(complexT) floatT

引数の型と戻り値の型が対応しています。complexの場合、2つの引数は同じ浮動小数点型でなければならず、戻り値の型は、対応する浮動小数点構成要素を持つ複素数型です:float32の引数にはcomplex64、float64の引数にはcomplex128です。引数の1つが型付けされていない定数として評価される場合、それは最初に他の引数の型に暗黙的に変換されます。両方の引数が型付けされていない定数として評価される場合、それらは非複素数でなければならず、あるいはそれらの虚数部はゼロでなければならず、関数の戻り値は型付けされていない複素数定数となります。

realとimagの場合、引数は複素数型でなければならず、戻り値の型は対応する浮動小数点型です:complex64の引数にはfloat32、complex128の引数にはfloat64です。引数が型付けされていない定数として評価される場合、それは数値でなければならず、関数の戻り値は型付けされていない浮動小数点定数となります。

real関数とimag関数は対でcomplexの逆数を構成するので、複素数型Zの値zに対しては、z == Z(complex(real(z), imag(z)))となります。

パニックへの対応

編集

panicrecover という2つの組込み関数は、ランタイムパニックやプログラム定義のエラー状態の報告と処理を支援します[17]

ブートストラップ

編集

現在の実装では、ブートストラップの際に便利ないくつかの組み込み関数が用意されています。これらの関数は完成度を高めるために文書化されていますが、言語として残ることは保証されていません。これらの関数は結果を返しません[18]

ブートストラップ
関数 動作
print すべての引数を表示します。引数のフォーマットは実装によって異なります。
println printと同じですが、引数の間にスペースを入れ、最後に改行を入れます。

脚註

編集
  1. ^ “Keywords ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Keywords. 
  2. ^ ユニバースブロック(universe block)は、すべてのGoソーステキストを包含しています。
  3. ^ “Predeclared identifiers ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Predeclared_identifiers. 
  4. ^ “Types ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Types. "The language predeclares certain type names. Others are introduced with type declarations." 
  5. ^ 5.0 5.1 “Built-in functions ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Built-in_functions. 
  6. ^ “Boolean types ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Boolean_types. 
  7. ^ “Numeric types ¶”. The Go Programming Language Specification. The Go website. (March 10, 2022). https://go.dev/ref/spec#Numeric_types. 
  8. ^ “String types ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#String_types. 
  9. ^ “Errors ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Errors. 
  10. ^ “Close ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Close. 
  11. ^ “Length_and_capacity ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Length_and_capacity. 
  12. ^ “Allocation ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Allocation. 
  13. ^ “Making slices maps and channels ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Making_slices_maps_and_channels. 
  14. ^ “Appending and copying slices ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Appending_and_copying_slices. 
  15. ^ “Deletion of map elements ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Deletion_of_map_elements. 
  16. ^ “Manipulating complex numbers ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Complex_numbers. 
  17. ^ “Handling panics ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Handling_panics. 
  18. ^ “Bootstrapping ¶”. The Go Programming Language Specification. The Go website. (2024-06-13). https://go.dev/ref/spec#Bootstrapping.