組み込み関数

組み込み関数は事前に宣言されています。これらは他の関数と同様に呼び出されますが、いくつかの関数は最初の引数として式の代わりに型を受け取ります。

組み込み関数は標準のGo型を持たないため、関数呼び出し式でのみ使用可能で、関数値として使用することはできません。

スライスの追加とコピー

組み込み関数 appendcopy は一般的なスライス操作に役立ちます。両方の関数において、引数が参照するメモリが重複しているかどうかにかかわらず、結果は独立しています。

可変引数関数 append はスライス s(型 S)に0個以上の値 x を追加し、結果として得られるスライス(同じく型 S)を返します。値 x は型 ...E のパラメータに渡されます。ここで ES の要素型であり、それぞれのパラメータ渡しのルールが適用されます。特殊なケースとして、append は最初の引数として型 []byte に割り当て可能な値と、2番目の引数として文字列型の後に ... を付けた値も受け付けます。この形式は文字列のバイトを追加します。

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

S が型パラメータの場合、そのタイプセット内のすべての型は同じ基本スライス型 []E を持つ必要があります。

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

s0 := []int{0, 0}
s1 := append(s0, 2)                // 単一要素の追加     s1 は []int{0, 0, 2}
s2 := append(s1, 3, 5, 7)          // 複数要素の追加    s2 は []int{0, 0, 2, 3, 5, 7}
s3 := append(s2, s0...)            // スライスの追加    s3 は []int{0, 0, 2, 3, 5, 7, 0, 0}
s4 := append(s3[3:6], s3[2:]...)   // 重複するスライスの追加    s4 は []int{3, 5, 7, 2, 3, 5, 7, 0, 0}

var t []interface{}
t = append(t, 42, 3.1415, "foo")   //                             t は []interface{}{42, 3.1415, "foo"}

var b []byte
b = append(b, "bar"...)            // 文字列内容の追加      b は []byte{'b', 'a', 'r' }

関数 copy はソース src からデスティネーション dst へスライス要素をコピーし、コピーされた要素の数を返します。両方の引数は同一の要素型 E を持ち、型 []E のスライスに割り当て可能でなければなりません。コピーされる要素の数は len(src)len(dst) の小さい方になります。特殊なケースとして、copy はデスティネーション引数として型 []byte に割り当て可能な値と、ソース引数として string 型の値も受け付けます。この形式は文字列からのバイトをバイトスライスにコピーします。

copy(dst, src []T) int
copy(dst []byte, src string) int

引数の1つまたは両方の型が型パラメータの場合、それぞれのタイプセット内のすべての型は同じ基本スライス型 []E を持つ必要があります。

例:

var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
var s = make([]int, 6)
var b = make([]byte, 5)
n1 := copy(s, a[0:])            // n1 == 6, s は []int{0, 1, 2, 3, 4, 5}
n2 := copy(s, s[2:])            // n2 == 4, s は []int{2, 3, 4, 5, 4, 5}
n3 := copy(b, "Hello, World!")  // n3 == 5, b は []byte("Hello")

クリア

組み込み関数 clear は マップ、スライス、または型パラメータ型の引数を取り、すべての要素を削除またはゼロにします [Go 1.21]。

Call        引数型           結果

clear(m)    map[K]T         すべてのエントリを削除し、空のマップにする (len(m) == 0)

clear(s)    []T             s の長さまですべての要素を T のゼロ値に設定する

clear(t)    型パラメータ    下記参照

clear への引数の型が型パラメータである場合、そのタイプセット内のすべての型はマップまたはスライスでなければならず、clear は実際の型引数に対応する操作を実行します。

マップまたはスライスが nil の場合、clear は何も行いません。

クローズ

チャネル ch に対して、組み込み関数 close(ch) はそのチャネルにこれ以上値が送信されないことを記録します。ch が受信専用チャネルの場合はエラーとなります。閉じられたチャネルへの送信や閉鎖は実行時パニックを引き起こします。nilチャネルの閉鎖も実行時パニックを引き起こします。close を呼び出した後、そして以前に送信された値がすべて受信された後、受信操作はブロックせずにチャネルの型のゼロ値を返します。複数値の受信操作は、受信した値とチャネルが閉じられているかどうかの表示を共に返します。

close への引数の型が型パラメータである場合、そのタイプセット内のすべての型は同じ要素型を持つチャネルでなければなりません。それらのチャネルのいずれかが受信専用チャネルである場合はエラーとなります。

複素数の操作

3つの関数が複素数の組み立てと分解を行います。組み込み関数 complex は浮動小数点の実部と虚部から複素数値を構築し、realimag は複素数値から実部と虚部を抽出します。

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

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

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

realimag 関数は合わせて complex の逆関数を形成します。したがって、複素数型 Z の値 z に対して、z == Z(complex(real(z), imag(z))) となります。

これらの関数のオペランドがすべて定数である場合、戻り値は定数となります。

var a = complex(2, -2)             // complex128
const b = complex(1.0, -1.4)       // 型なし複素定数 1 - 1.4i
x := float32(math.Cos(math.Pi/2))  // float32
var c64 = complex(5, -x)           // complex64
var s int = complex(1, 0)          // 型なし複素定数 1 + 0i は int に変換可能
_ = complex(1, 2<<s)               // 不正: 2 は浮動小数点型と見なされ、シフトできない
var rl = real(c64)                 // float32
var im = imag(a)                   // float64
const c = imag(b)                  // 型なし定数 -1.4
_ = imag(3 << s)                   // 不正: 3 は複素数型と見なされ、シフトできない

型パラメータ型の引数は許可されていません。

マップ要素の削除

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

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

m の型が型パラメータである場合、そのタイプセット内のすべての型はマップでなければならず、それらはすべて同一のキー型を持つ必要があります。

マップ mnil であるか、要素 m[k] が存在しない場合、delete は何も行いません。

長さと容量

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

呼び出し    引数型           結果

len(s)      string型         文字列の長さ(バイト単位)
            [n]T, *[n]T      配列の長さ(== n)
            []T              スライスの長さ
            map[K]T          マップの長さ(定義されたキーの数)
            chan T           チャネルバッファにキューイングされた要素の数
            型パラメータ     下記参照

cap(s)      [n]T, *[n]T      配列の長さ(== n)
            []T              スライスの容量
            chan T           チャネルバッファの容量
            型パラメータ     下記参照

引数型が型パラメータ P である場合、呼び出し len(e)(または cap(e) )は P のタイプセット内の各型に対して有効でなければなりません。結果は、P がインスタンス化された型引数に対応する型を持つ引数の長さ(または容量)です。

スライスの容量は、基底配列内で割り当てられているスペースがある要素の数です。常に次の関係が成り立ちます:

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

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

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

const (
	c1 = imag(2i)                    // imag(2i) = 2.0 は定数
	c2 = len([10]float64{2})         // [10]float64{2} には関数呼び出しが含まれていない
	c3 = len([10]float64{c1})        // [10]float64{c1} には関数呼び出しが含まれていない
	c4 = len([10]float64{imag(2i)})  // imag(2i) は定数で、関数呼び出しは発行されない
	c5 = len([10]float64{imag(z)})   // 無効: imag(z) は(非定数の)関数呼び出し
)
var z complex128

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

組み込み関数 make は型 T(スライス、マップ、チャネル型、または型パラメータでなければならない)を取り、オプションで型固有の式リストが続きます。型 T の値を返します(*T ではありません)。メモリは初期値のセクションで説明されているように初期化されます。

呼び出し          型 T             結果

make(T, n)        スライス         長さ n、容量 n の型 T のスライス
make(T, n, m)     スライス         長さ n、容量 m の型 T のスライス

make(T)           マップ           型 T のマップ
make(T, n)        マップ           約 n 個の要素の初期スペースを持つ型 T のマップ

make(T)           チャネル         型 T の非バッファ付きチャネル
make(T, n)        チャネル         型 T のバッファサイズ n のバッファ付きチャネル

make(T, n)        型パラメータ     下記参照
make(T, n, m)     型パラメータ     下記参照

最初の引数が型パラメータである場合、そのタイプセット内のすべての型は同じ基本型を持たなければならず、それはスライスまたはマップ型でなければなりません。または、チャネル型がある場合は、チャネル型のみでなければならず、それらはすべて同じ要素型を持ち、チャネルの方向が競合してはいけません。

サイズ引数 nm はそれぞれ整数型、整数型のみを含むタイプセットを持つ、または型なし定数でなければなりません。定数サイズ引数は非負で、int 型の値で表現可能でなければなりません。型なし定数の場合、それには int 型が与えられます。nm の両方が提供され、定数である場合、nm より大きくてはいけません。スライスとチャネルの場合、実行時に n が負または m より大きい場合、実行時パニックが発生します。

s := make([]int, 10, 100)       // len(s) == 10, cap(s) == 100 のスライス
s := make([]int, 1e3)           // len(s) == cap(s) == 1000 のスライス
s := make([]int, 1<<63)         // 不正: len(s) は int 型の値で表現できない
s := make([]int, 10, 0)         // 不正: len(s) > cap(s)
c := make(chan int, 10)         // バッファサイズ 10 のチャネル
m := make(map[string]int, 100)  // 約 100 要素の初期スペースを持つマップ

サイズヒント n を持つマップ型で make を呼び出すと、n マップ要素を保持するための初期スペースを持つマップが作成されます。正確な動作は実装依存です。

最小値と最大値

組み込み関数 minmax は、順序付けられた型の固定数の引数の最小値または最大値をそれぞれ計算します。少なくとも1つの引数が必要です [Go 1.21]。

演算子と同じ型ルールが適用されます:順序付けられた引数 xy に対して、x + y が有効であれば min(x, y) も有効で、min(x, y) の型は x + y の型と同じです(max も同様)。すべての引数が定数の場合、結果は定数となります。

var x, y int
m := min(x)                 // m == x
m := min(x, y)              // m は x と y の小さい方
m := max(x, y, 10)          // m は x と y の大きい方だが、少なくとも 10
c := max(1, 2.0, 10)        // c == 10.0 (浮動小数点型)
f := max(0, float32(x))     // f の型は float32
var s []string
_ = min(s...)               // 無効: スライス引数は許可されていない
t := max("", "foo", "bar")  // t == "foo" (文字列型)

数値引数の場合、すべての NaN が等しいと仮定すると、minmax は可換性と結合性があります:

min(x, y)    == min(y, x)
min(x, y, z) == min(min(x, y), z) == min(x, min(y, z))

浮動小数点引数の負のゼロ、NaN、および無限大に対しては、次のルールが適用されます:

   x        y    min(x, y)    max(x, y)

  -0.0    0.0         -0.0          0.0    // 負のゼロは(非負の)ゼロより小さい
  -Inf      y         -Inf            y    // 負の無限大は他のどの数よりも小さい
  +Inf      y            y         +Inf    // 正の無限大は他のどの数よりも大きい
   NaN      y          NaN          NaN    // 引数のいずれかが NaN の場合、結果は NaN

文字列引数の場合、min の結果は(または max の場合は最大値)値が最小の最初の引数で、バイト単位でレキシカルに比較されます:

min(x, y)    == x <= y の場合 x、そうでなければ y
min(x, y, z) == min(min(x, y), z)

メモリ割り当て

組み込み関数 new は型 T を取り、実行時にその型の変数用のストレージを割り当て、それを指すポインタ型 *T の値を返します。変数は初期値のセクションで説明されているように初期化されます。

new(T)

例えば

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

これは型 S の変数用のストレージを割り当て、初期化し(a=0b=0.0)、場所のアドレスを含む型 *S の値を返します。

パニックの処理

2つの組み込み関数 panicrecover は、実行時パニックとプログラム定義のエラー条件の報告と処理を支援します。

func panic(interface{})
func recover() interface{}

関数 F を実行中に、panic の明示的な呼び出しまたは実行時パニックが発生すると、F の実行は終了します。F により遅延された関数は通常通り実行されます。次に、F の呼び出し元により遅延された関数が実行され、実行中のゴルーチンのトップレベル関数まで遡ります。その時点でプログラムは終了し、panic への引数の値を含むエラー条件が報告されます。この終了シーケンスはパニックと呼ばれます。

panic(42)
panic("unreachable")
panic(Error("cannot parse"))

recover 関数を使用すると、プログラムはパニック状態のゴルーチンの動作を管理できます。関数 Grecover を呼び出す関数 D を遅延させ、G が実行されているのと同じゴルーチン上の関数でパニックが発生したとします。遅延関数の実行が D に達すると、Drecover 呼び出しの戻り値は panic の呼び出しに渡された値になります。D が新しい panic を開始せずに正常に戻ると、パニックシーケンスは停止します。その場合、Gpanic の呼び出しの間に呼び出された関数の状態は破棄され、通常の実行が再開されます。D の前に G により遅延された関数が実行され、G の実行は呼び出し元に戻ることで終了します。

ゴルーチンがパニック状態でない場合、または recover が遅延関数によって直接呼び出されなかった場合、recover の戻り値は nil です。逆に、ゴルーチンがパニック状態で、recover が遅延関数によって直接呼び出された場合、recover の戻り値は nil ではないことが保証されています。これを確実にするため、nil インターフェース値(または型なし nil)での panic の呼び出しは実行時パニックを引き起こします。

以下の例の protect 関数は、関数引数 g を呼び出し、呼び出し元を g によって発生した実行時パニックから保護します。

func protect(g func()) {
	defer func() {
		log.Println("done")  // パニックがあっても Println は正常に実行される
		if x := recover(); x != nil {
			log.Printf("run time panic: %v", x)
		}
	}()
	log.Println("start")
	g()
}

ブートストラップ

現在の実装では、ブートストラップ中に役立ついくつかの組み込み関数が提供されています。これらの関数は完全性のために文書化されていますが、言語に残ることは保証されていません。これらは結果を返しません。

関数      動作

print     すべての引数を出力する。引数のフォーマットは実装固有
println   print と同様だが、引数間にスペースを入れ、最後に改行を追加

実装制限:printprintln は任意の引数型を受け入れる必要はありませんが、ブール値、数値、および文字列型の出力はサポートされていなければなりません。