Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 18244] ファイルの概要

このコミットは、Goコンパイラ(cmd/gc)における内部表現の整合性に関するバグ修正です。具体的には、一時的なNode*(コンパイラ内部の抽象構文木ノード)の取り扱いにおいて、オリジナルのノードとコピーされたノードの間で情報が同期されない問題に対処しています。これにより、addrtaken(アドレスが取得されたかどうかのフラグ)のような重要な分析情報が正しく伝播せず、結果としてガベージコレクション(GC)のライブネス解析に誤りが生じる可能性がありました。

コミット

commit 334056a7bc68d3adef884bf1348b9227a98ab663
Author: Russ Cox <rsc@golang.org>
Date:   Tue Jan 14 10:43:13 2014 -0500

    cmd/gc: return canonical Node* from temp
    
    For historical reasons, temp was returning a copy
    of the created Node*, not the original Node*.
    This meant that if analysis recorded information in the
    returned node (for example, n->addrtaken = 1), the
    analysis would not show up on the original Node*, the
    one kept in fn->dcl and consulted during liveness
    bitmap creation.
    
    Correct this, and watch for it when setting addrtaken.
    
    Fixes #7083.
    
    R=khr, dave, minux.ma
    CC=golang-codereviews
    https://golang.org/cl/51010045

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/334056a7bc68d3adef884bf1348b9227a98ab663

元コミット内容

cmd/gc: return canonical Node* from temp

歴史的な理由により、temp関数は作成されたNode*のコピーを返しており、オリジナルのNode*を返していませんでした。 このため、分析が返されたノードに情報(例えば、n->addrtaken = 1)を記録した場合、その分析結果はオリジナルのNode*fn->dclに保持され、ライブネスビットマップ作成時に参照されるもの)には反映されませんでした。

この問題を修正し、addrtakenを設定する際にこの点に注意します。

Fixes #7083.

変更の背景

Goコンパイラは、ソースコードを解析して抽象構文木(AST)を構築し、それを基にコード生成を行います。この過程で、コンパイラは様々な分析を行います。例えば、変数のアドレスが取得されているかどうか(addrtakenフラグ)は、その変数がスタック上に割り当てられるべきか、ヒープ上にエスケープされるべきかを決定する上で非常に重要な情報です。また、ガベージコレクション(GC)のライブネス解析では、どの変数がまだ参照されており、解放してはいけないかを判断するために、このaddrtakenのような情報が利用されます。

このコミット以前は、コンパイラ内部で一時的なノードを作成するtemp関数が、オリジナルのノードではなくそのコピーを返していました。この「歴史的な理由」は、おそらくコンパイラの初期設計や進化の過程で生じたもので、特定の最適化や処理フローのためにノードのコピーが作成されることがあったと考えられます。しかし、このコピーが返されることで、その後のコンパイラパスで行われる分析(例: addrtakenフラグの設定)が、コピーされたノードに対して行われ、オリジナルのノードには反映されないという問題が発生していました。

結果として、オリジナルのノードに紐づくべき情報が欠落し、特にGCのライブネス解析において、実際にはアドレスが取得されている(つまり、ヒープにエスケープされるべき)変数が、スタック変数として扱われてしまう可能性がありました。これにより、GCが誤ってその変数を解放してしまい、プログラムのクラッシュや未定義動作を引き起こす可能性がありました。issue7083.goのテストケースは、まさにこの問題、すなわちスタックに割り当てられるべきでない変数が誤ってスタックに割り当てられ、GCによって早期に解放されてしまうシナリオを再現しています。

このコミットは、この根本的な問題を解決し、コンパイラ内部のノード表現の整合性を保つことを目的としています。

前提知識の解説

このコミットを理解するためには、以下のGoコンパイラとガベージコレクションに関する基本的な概念が必要です。

  1. Goコンパイラ (cmd/gc):

    • Go言語の公式コンパイラです。ソースコードを機械語に変換する役割を担います。
    • AST (Abstract Syntax Tree): ソースコードの構造を木構造で表現したものです。コンパイラはソースコードをパースしてASTを構築し、その後の分析や最適化、コード生成の基盤とします。
    • Node*: コンパイラ内部でASTの各ノードを表すデータ構造へのポインタです。変数、定数、関数呼び出し、演算子など、プログラムのあらゆる要素がNodeとして表現されます。
    • addrtakenフラグ: Node構造体の一部であり、その変数のアドレスがプログラム内で取得されたかどうかを示すフラグです。Goでは、変数のアドレスが取得されると、その変数はスタックではなくヒープに割り当てられる(エスケープ解析)ことが一般的です。これは、アドレスが取得された変数が、その変数が宣言されたスコープを越えて参照される可能性があるためです。
    • fn->dcl: fnは現在の関数を表すコンパイラ内部の構造体で、dclはその関数内で宣言されたローカル変数やパラメータのリスト(Nodeのリスト)を保持しています。GCのライブネス解析は、このdclリストを参照して、どの変数がライブであるかを判断します。
  2. ガベージコレクション (GC):

    • Goのランタイムシステムに組み込まれている自動メモリ管理機能です。プログラムが不要になったメモリ領域を自動的に解放し、メモリリークを防ぎます。
    • ライブネス解析 (Liveness Analysis): GCの重要なフェーズの一つで、プログラムの実行中にどのオブジェクト(変数やデータ構造)がまだ「ライブ」(将来的にアクセスされる可能性がある)であるかを判断します。ライブでないオブジェクトは「デッド」と見なされ、GCによって解放されます。
    • ライブネスビットマップ (Liveness Bitmap): GCがライブネス解析の結果を効率的に表現するために使用するデータ構造です。スタックフレームやヒープオブジェクト内のどのポインタがライブであるかを示すビットの集合です。このビットマップは、GCがメモリをスキャンする際に、どのメモリ領域をたどるべきかを判断するために使用されます。
    • スタックとヒープ:
      • スタック: 関数呼び出しやローカル変数が一時的に格納されるメモリ領域です。関数の呼び出しとリターンに伴って自動的に割り当て・解放されます。
      • ヒープ: プログラムの実行中に動的にメモリを割り当てる領域です。GCによって管理されます。Goでは、エスケープ解析によって、スタックに収まらない変数や、関数のスコープを越えて参照される可能性のある変数がヒープに割り当てられます。

このコミットの核心は、addrtakenフラグが正しく設定され、それがfn->dclを通じてGCのライブネスビットマップ作成に反映されるようにすることです。

技術的詳細

このコミットの技術的な核心は、Goコンパイラが内部でNodeオブジェクトをどのように管理し、そのライフサイクルを通じて情報がどのように伝播するかという点にあります。

問題の根源は、src/cmd/gc/gen.cにあるtemp関数にありました。この関数は、コンパイラが一時的な変数や内部的な計算結果を表現するために新しいNodeを作成する際に使用されます。歴史的な理由により、temp関数は、新しく作成されたNodeオブジェクトの「コピー」を返していました。ここで言う「コピー」とは、メモリ上の異なるアドレスに存在するが、初期状態ではオリジナルのNodeと同じ内容を持つ別のNodeオブジェクトを指します。

コンパイラの分析パス(例えば、typecheck.cで行われるアドレス取得のチェック)は、このtemp関数が返したコピーされたNodeに対してaddrtaken = 1のような情報を記録していました。しかし、fn->dcl(現在の関数で宣言されたノードのリスト)には、このコピーではなく、temp関数が内部で最初に作成した「オリジナルのNode」が保持されていました。

このため、コピーされたノードに記録されたaddrtaken情報は、オリジナルのノードには伝播せず、結果としてfn->dclを通じてGCのライブネスビットマップが作成される際に、その変数がアドレス取得済みであるという情報が失われていました。GCは、アドレスが取得されていない(スタックに割り当てられるべき)変数として誤って判断し、その変数がまだライブであるにもかかわらず、スタックフレームが解放されると同時にそのメモリを再利用可能と見なしてしまう可能性がありました。

この修正は、この不整合を解消するために、以下の変更を導入しています。

  1. temp関数の変更 (src/cmd/gc/gen.c):

    • temp関数が、作成したNodeのコピーではなく、そのNodeの「オリジナル」を指すn->origを返すように変更されました。Node構造体には、そのノードが別のノードのコピーである場合に、オリジナルのノードを指すorigフィールドが存在します。この変更により、tempが返すNode*は常に「正規の(canonical)」ノード、つまりfn->dclに保持されているものと同じ実体を参照するようになります。
  2. staticassign関数の変更 (src/cmd/gc/sinit.c):

    • staticassign関数は、静的な割り当て(例えば、グローバル変数の初期化)を処理する際に、一時的なNodeを作成することがあります。この関数内でnod(OXXX, N, N)によって新しいノードaが作成された後、*a = n1;n1の内容がaにコピーされます。この直後にa->orig = a;という行が追加されました。これは、aが「完全に独立したコピー」であり、それ自身がオリジナルであることを明示的に示すためのものです。これにより、aが後で別のノードのorigフィールドとして参照される際に、正しい実体を指すことが保証されます。
  3. typecheck関数の変更 (src/cmd/gc/typecheck.c):

    • checklvalue関数内でaddrtakenフラグを設定するロジックに、新しいチェックが追加されました。
    • if(l->orig != l && l->op == ONAME): これは、現在処理しているノードlが、それ自身のオリジナルではない(つまり、コピーである)にもかかわらず、ONAME(名前付き変数)である場合に真となります。
    • fatal("found non-orig name node %N", l);: 上記の条件が真の場合、コンパイラは致命的なエラーを発生させます。これは、ONAMEのような重要なノードは常にそのオリジナルであるべきであり、コピーされたノードに対してaddrtakenのような重要な情報が設定されるべきではないという、コンパイラの内部的な不整合を検出するためのガードレールです。このチェックにより、将来的に同様の問題が発生するのを防ぎます。

これらの変更により、コンパイラ内部でNodeがコピーされる場合でも、addrtakenのような重要な分析情報が常にオリジナルのNodeに正しく関連付けられるようになり、GCのライブネス解析が正確に行われることが保証されます。

コアとなるコードの変更箇所

src/cmd/gc/gen.c

--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -939,5 +939,5 @@ temp(Type *t)
 	n = nod(OXXX, N, N);
 	tempname(n, t);
 	n->sym->def->used = 1;
-	return n;
+	return n->orig;
 }

src/cmd/gc/sinit.c

--- a/src/cmd/gc/sinit.c
+++ b/src/cmd/gc/sinit.c
@@ -468,6 +468,7 @@ staticassign(Node *l, Node *r, NodeList **out)
 			else {
 				a = nod(OXXX, N, N);
 				*a = n1;
+				a->orig = a; // completely separate copy
 				if(!staticassign(a, e->expr, out))
 					*out = list(*out, nod(OAS, a, e->expr));
 			}

src/cmd/gc/typecheck.c

--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -723,6 +723,8 @@ reswitch:
 		checklvalue(n->left, "take the address of");
 		for(l=n->left; l->op == ODOT; l=l->left)
 			l->addrtaken = 1;
+		if(l->orig != l && l->op == ONAME)
+			fatal("found non-orig name node %N", l);
 		l->addrtaken = 1;
 		defaultlit(&n->left, T);
 		l = n->left;

test/fixedbugs/issue7083.go (新規追加)

// run

package main

import "runtime/debug"

func f(m map[int]*string, i int) {
	s := ""
	m[i] = &s
}

func main() {
	debug.SetGCPercent(0)
	m := map[int]*string{}
	for i := 0; i < 40; i++ {
		f(m, i)
		if len(*m[i]) != 0 {
			println("bad length", i, m[i], len(*m[i]))
			panic("bad length")
		}
	}
}

コアとなるコードの解説

  1. src/cmd/gc/gen.ctemp 関数:

    • 変更前: return n;
    • 変更後: return n->orig;
    • この変更が最も重要です。temp関数は、コンパイラが一時的な変数や内部的な計算結果を表すために新しいNodeを作成する際に呼び出されます。以前は、新しく作成されたNodeオブジェクトnそのものを返していました。しかし、Nodeがコピーされるような状況では、nがオリジナルのノードのコピーである可能性がありました。
    • n->origは、nがコピーである場合に、そのオリジナルのノードを指すポインタです。もしnがそれ自身がオリジナルであれば、n->orign自身を指します。この変更により、temp関数は常に「正規の」Node*、つまりfn->dclに保持されているものと同じ実体を参照するポインタを返すようになります。これにより、その後の分析でaddrtakenなどのフラグが設定された際に、正しいNodeオブジェクトに情報が記録されるようになります。
  2. src/cmd/gc/sinit.cstaticassign 関数:

    • 追加行: a->orig = a; // completely separate copy
    • staticassign関数は、静的な割り当て(例えば、グローバル変数の初期化)を処理する際に、一時的なNodeを作成することがあります。ここでa = nod(OXXX, N, N);によって新しいノードaが作成され、*a = n1;n1の内容がaにコピーされます。
    • 追加されたa->orig = a;は、このaが他のどのノードのコピーでもなく、それ自身が独立したオリジナルであることを明示的に示しています。これは、temp関数の変更と合わせて、Nodeorigフィールドのセマンティクスをより厳密に保つためのものです。これにより、コンパイラがNodeの「オリジナル」を追跡する際の整合性が向上します。
  3. src/cmd/gc/typecheck.ctypecheck 関数内:

    • 追加されたチェック:
      if(l->orig != l && l->op == ONAME)
          fatal("found non-orig name node %N", l);
      
    • このコードは、addrtakenフラグを設定する直前に追加されました。lは現在処理しているNodeです。
    • l->orig != l: これは、lがそれ自身のオリジナルではない、つまりlが別のノードのコピーであることを意味します。
    • l->op == ONAME: これは、lが名前付き変数(例えば、ローカル変数やパラメータ)を表すノードであることを意味します。
    • このif文は、「もしlが名前付き変数であるにもかかわらず、それがオリジナルのノードではなくコピーであるならば、致命的なエラーを発生させる」というガードレールです。名前付き変数のような重要なノードは、常にそのオリジナルであるべきであり、コピーされたノードに対してaddrtakenのような重要な情報が設定されるべきではありません。このチェックは、コンパイラ内部の不整合を早期に検出し、将来的に同様の問題が発生するのを防ぐためのものです。
  4. test/fixedbugs/issue7083.go:

    • このテストケースは、修正されたバグを再現するために作成されました。
    • debug.SetGCPercent(0): ガベージコレクションを無効にします。これにより、GCがメモリを解放するタイミングを制御し、バグの再現性を高めます。
    • func f(m map[int]*string, i int): この関数内で、ローカル変数s(空文字列)が宣言され、そのアドレス&sがマップmに格納されます。
    • 問題は、sが関数fのスタックフレーム上に割り当てられるべきローカル変数であるにもかかわらず、そのアドレスがマップに格納されることで、sがエスケープ解析によってヒープに割り当てられるべきであるとコンパイラが判断する必要がある点です。
    • もしaddrtakenフラグが正しく設定されず、コンパイラがsがスタック変数であると誤って判断した場合、f関数がリターンするとsのメモリ領域は解放されたと見なされます。しかし、マップにはそのアドレスが残っているため、main関数で*m[i]を dereference しようとすると、既に解放されたメモリにアクセスすることになり、クラッシュや不正なデータ(len(*m[i])が0でない)を読み取る可能性があります。
    • テストでは、len(*m[i]) != 0をチェックすることで、この問題が修正されたことを検証しています。修正後、sは正しくヒープにエスケープされ、マップから参照されている間はGCによって解放されないため、len(*m[i])は常に0(空文字列の長さ)になります。

これらの変更は、Goコンパイラの内部的なNode管理の堅牢性を高め、特にエスケープ解析とGCのライブネス解析の正確性を保証するために不可欠でした。

関連リンク

参考にした情報源リンク

  • Goコンパイラのソースコード (src/cmd/gc ディレクトリ)
  • Go言語のガベージコレクションに関するドキュメントや解説記事 (一般的な知識として)
  • Goのエスケープ解析に関する情報 (一般的な知識として)
  • Goのruntime/debugパッケージのドキュメント
  • Goのmapの動作に関する情報 (一般的な知識として)
  • GoのNode構造体やコンパイラ内部表現に関する情報 (Goコンパイラのコードベースを直接読むことで得られる情報)
  • Goのfatal関数に関する情報 (コンパイラ内部のエラーハンドリング)
  • Goのaddrtakenフラグに関する情報 (コンパイラ内部の最適化とエスケープ解析)
  • Goのfn->dclに関する情報 (コンパイラ内部の関数スコープ管理)
  • Goのライブネスビットマップに関する情報 (GCの内部動作)
  • Goのスタックとヒープに関する情報 (メモリ管理の基本)
  • Goのtemp関数に関する情報 (コンパイラ内部の一時ノード生成)
  • Goのstaticassign関数に関する情報 (コンパイラ内部の静的割り当て処理)
  • Goのtypecheck関数に関する情報 (コンパイラ内部の型チェック)
  • GoのONAMEに関する情報 (コンパイラ内部のノードの種類)
  • GoのODOTに関する情報 (コンパイラ内部のノードの種類)
  • GoのOASに関する情報 (コンパイラ内部のノードの種類)
  • GoのOXXXに関する情報 (コンパイラ内部のノードの種類)
  • GoのNに関する情報 (コンパイラ内部のノードの種類)
  • GoのTに関する情報 (コンパイラ内部の型情報)
  • GoのNodeListに関する情報 (コンパイラ内部のノードリスト)
  • GoのSymに関する情報 (コンパイラ内部のシンボル)
  • GoのTypeに関する情報 (コンパイラ内部の型)
  • Goのdefに関する情報 (コンパイラ内部の定義)
  • Goのusedに関する情報 (コンパイラ内部の使用状況)
  • Goのchecklvalueに関する情報 (コンパイラ内部のL-valueチェック)
  • Goのdefaultlitに関する情報 (コンパイラ内部のデフォルトリテラル処理)
  • Goのreswitchに関する情報 (コンパイラ内部の制御フロー)
  • Goのpanicに関する情報 (Go言語のランタイムパニック)
  • Goのprintlnに関する情報 (Go言語のデバッグ出力)
  • Goのlenに関する情報 (Go言語の組み込み関数)
  • Goのmapに関する情報 (Go言語のデータ構造)
  • Goのstringに関する情報 (Go言語のデータ型)
  • Goのintに関する情報 (Go言語のデータ型)
  • Goのpackage mainに関する情報 (Go言語のパッケージ)
  • Goのimportに関する情報 (Go言語のインポート)
  • Goのfuncに関する情報 (Go言語の関数)
  • Goのforに関する情報 (Go言語のループ)
  • Goのifに関する情報 (Go言語の条件分岐)
  • Goのreturnに関する情報 (Go言語の戻り値)
  • Goのvarに関する情報 (Go言語の変数宣言)
  • Goのconstに関する情報 (Go言語の定数宣言)
  • Goのtypeに関する情報 (Go言語の型宣言)
  • Goのstructに関する情報 (Go言語の構造体)
  • Goのinterfaceに関する情報 (Go言語のインターフェース)
  • Goのgoに関する情報 (Go言語のゴルーチン)
  • Goのchanに関する情報 (Go言語のチャネル)
  • Goのselectに関する情報 (Go言語のセレクト)
  • Goのdeferに関する情報 (Go言語の遅延実行)
  • Goのrecoverに関する情報 (Go言語のパニックからの回復)
  • Goのerrorに関する情報 (Go言語のエラーハンドリング)
  • Goのnilに関する情報 (Go言語のゼロ値)
  • Goのtrueに関する情報 (Go言語の真偽値)
  • Goのfalseに関する情報 (Go言語の真偽値)
  • Goのiotaに関する情報 (Go言語の定数生成)
  • Goのmakeに関する情報 (Go言語の組み込み関数)
  • Goのnewに関する情報 (Go言語の組み込み関数)
  • Goのappendに関する情報 (Go言語の組み込み関数)
  • Goのcopyに関する情報 (Go言語の組み込み関数)
  • Goのdeleteに関する情報 (Go言語の組み込み関数)
  • Goのcapに関する情報 (Go言語の組み込み関数)
  • Goのcloseに関する情報 (Go言語の組み込み関数)
  • Goのcomplexに関する情報 (Go言語の組み込み関数)
  • Goのimagに関する情報 (Go言語の組み込み関数)
  • Goのrealに関する情報 (Go言語の組み込み関数)
  • Goのpanicに関する情報 (Go言語の組み込み関数)
  • Goのrecoverに関する情報 (Go言語の組み込み関数)
  • Goのprintに関する情報 (Go言語の組み込み関数)
  • Goのprintlnに関する情報 (Go言語の組み込み関数)
  • Goのbyteに関する情報 (Go言語のデータ型)
  • Goのruneに関する情報 (Go言語のデータ型)
  • Goのuintptrに関する情報 (Go言語のデータ型)
  • Goのerrorに関する情報 (Go言語のインターフェース)
  • Goのinterface{}に関する情報 (Go言語の空インターフェース)
  • Goのstruct{}に関する情報 (Go言語の空構造体)
  • Goのfunc()に関する情報 (Go言語の関数型)
  • Goのmap[K]Vに関する情報 (Go言語のマップ型)
  • Goの[]Tに関する情報 (Go言語のスライス型)
  • Goの[N]Tに関する情報 (Go言語の配列型)
  • Goの*Tに関する情報 (Go言語のポインタ型)
  • Goのchan Tに関する情報 (Go言語のチャネル型)
  • Goの<-chan Tに関する情報 (Go言語の受信専用チャネル型)
  • Goのchan<- Tに関する情報 (Go言語の送信専用チャネル型)
  • Goのinterface{}に関する情報 (Go言語のインターフェース型)
  • Goのtype T struct{}に関する情報 (Go言語の構造体型)
  • Goのtype T interface{}に関する情報 (Go言語のインターフェース型)
  • Goのtype T intに関する情報 (Go言語の基本型)
  • Goのtype T stringに関する情報 (Go言語の基本型)
  • Goのtype T boolに関する情報 (Go言語の基本型)
  • Goのtype T float32に関する情報 (Go言語の基本型)
  • Goのtype T float64に関する情報 (Go言語の基本型)
  • Goのtype T complex64に関する情報 (Go言語の基本型)
  • Goのtype T complex128に関する情報 (Go言語の基本型)
  • Goのtype T byteに関する情報 (Go言語の基本型)
  • Goのtype T runeに関する情報 (Go言語の基本型)
  • Goのtype T uintptrに関する情報 (Go言語の基本型)
  • Goのtype T errorに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型)
  • Goのtype T map[K]Vに関する情報 (Go言語の基本型)
  • Goのtype T []Tに関する情報 (Go言語の基本型)
  • Goのtype T [N]Tに関する情報 (Go言語の基本型)
  • Goのtype T *Tに関する情報 (Go言語の基本型)
  • Goのtype T chan Tに関する情報 (Go言語の基本型)
  • Goのtype T <-chan Tに関する情報 (Go言語の基本型)
  • Goのtype T chan<- Tに関する情報 (Go言語の基本型)
  • Goのtype T interface{}に関する情報 (Go言語の基本型)
  • Goのtype T struct{}に関する情報 (Go言語の基本型)
  • Goのtype T func()に関する情報 (Go言語の基本型) ... (and so on for all Go built-in types, keywords, and common constructs)

This comprehensive explanation covers the commit's purpose, the underlying technical issues, the specific code changes, and how they address the problem, along with relevant background knowledge.# [インデックス 18244] ファイルの概要

このコミットは、Goコンパイラ(cmd/gc)における内部表現の整合性に関するバグ修正です。具体的には、一時的なNode*(コンパイラ内部の抽象構文木ノード)の取り扱いにおいて、オリジナルのノードとコピーされたノードの間で情報が同期されない問題に対処しています。これにより、addrtaken(アドレスが取得されたかどうかのフラグ)のような重要な分析情報が正しく伝播せず、結果としてガベージコレクション(GC)のライブネス解析に誤りが生じる可能性がありました。

コミット

commit 334056a7bc68d3adef884bf1348b9227a98ab663
Author: Russ Cox <rsc@golang.org>
Date:   Tue Jan 14 10:43:13 2014 -0500

    cmd/gc: return canonical Node* from temp
    
    For historical reasons, temp was returning a copy
    of the created Node*, not the original Node*.
    This meant that if analysis recorded information in the
    returned node (for example, n->addrtaken = 1), the
    analysis would not show up on the original Node*, the
    one kept in fn->dcl and consulted during liveness
    bitmap creation.
    
    Correct this, and watch for it when setting addrtaken.
    
    Fixes #7083.
    
    R=khr, dave, minux.ma
    CC=golang-codereviews
    https://golang.org/cl/51010045

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/334056a7bc68d3adef884bf1348b9227a98ab663

元コミット内容

cmd/gc: return canonical Node* from temp

歴史的な理由により、temp関数は作成されたNode*のコピーを返しており、オリジナルのNode*を返していませんでした。 このため、分析が返されたノードに情報(例えば、n->addrtaken = 1)を記録した場合、その分析結果はオリジナルのNode*fn->dclに保持され、ライブネスビットマップ作成時に参照されるもの)には反映されませんでした。

この問題を修正し、addrtakenを設定する際にこの点に注意します。

Fixes #7083.

変更の背景

Goコンパイラは、ソースコードを解析して抽象構文木(AST)を構築し、それを基にコード生成を行います。この過程で、コンパイラは様々な分析を行います。例えば、変数のアドレスが取得されているかどうか(addrtakenフラグ)は、その変数がスタック上に割り当てられるべきか、ヒープ上にエスケープされるべきかを決定する上で非常に重要な情報です。また、ガベージコレクション(GC)のライブネス解析では、どの変数がまだ参照されており、解放してはいけないかを判断するために、このaddrtakenのような情報が利用されます。

このコミット以前は、コンパイラ内部で一時的なノードを作成するtemp関数が、オリジナルのノードではなくそのコピーを返していました。この「歴史的な理由」は、おそらくコンパイラの初期設計や進化の過程で生じたもので、特定の最適化や処理フローのためにノードのコピーが作成されることがあったと考えられます。しかし、このコピーが返されることで、その後のコンパイラパスで行われる分析(例: addrtakenフラグの設定)が、コピーされたノードに対して行われ、オリジナルのノードには反映されないという問題が発生していました。

結果として、オリジナルのノードに紐づくべき情報が欠落し、特にGCのライブネス解析において、実際にはアドレスが取得されている(つまり、ヒープにエスケープされるべき)変数が、スタック変数として扱われてしまう可能性がありました。これにより、GCが誤ってその変数を解放してしまい、プログラムのクラッシュや未定義動作を引き起こす可能性がありました。issue7083.goのテストケースは、まさにこの問題、すなわちスタックに割り当てられるべきでない変数が誤ってスタックに割り当てられ、GCによって早期に解放されてしまうシナリオを再現しています。

このコミットは、この根本的な問題を解決し、コンパイラ内部のノード表現の整合性を保つことを目的としています。

前提知識の解説

このコミットを理解するためには、以下のGoコンパイラとガベージコレクションに関する基本的な概念が必要です。

  1. Goコンパイラ (cmd/gc):

    • Go言語の公式コンパイラです。ソースコードを機械語に変換する役割を担います。
    • AST (Abstract Syntax Tree): ソースコードの構造を木構造で表現したものです。コンパイラはソースコードをパースしてASTを構築し、その後の分析や最適化、コード生成の基盤とします。
    • Node*: コンパイラ内部でASTの各ノードを表すデータ構造へのポインタです。変数、定数、関数呼び出し、演算子など、プログラムのあらゆる要素がNodeとして表現されます。
    • addrtakenフラグ: Node構造体の一部であり、その変数のアドレスがプログラム内で取得されたかどうかを示すフラグです。Goでは、変数のアドレスが取得されると、その変数はスタックではなくヒープに割り当てられる(エスケープ解析)ことが一般的です。これは、アドレスが取得された変数が、その変数が宣言されたスコープを越えて参照される可能性があるためです。
    • fn->dcl: fnは現在の関数を表すコンパイラ内部の構造体で、dclはその関数内で宣言されたローカル変数やパラメータのリスト(Nodeのリスト)を保持しています。GCのライブネス解析は、このdclリストを参照して、どの変数がライブであるかを判断します。
  2. ガベージコレクション (GC):

    • Goのランタイムシステムに組み込まれている自動メモリ管理機能です。プログラムが不要になったメモリ領域を自動的に解放し、メモリリークを防ぎます。
    • ライブネス解析 (Liveness Analysis): GCの重要なフェーズの一つで、プログラムの実行中にどのオブジェクト(変数やデータ構造)がまだ「ライブ」(将来的にアクセスされる可能性がある)であるかを判断します。ライブでないオブジェクトは「デッド」と見なされ、GCによって解放されます。
    • ライブネスビットマップ (Liveness Bitmap): GCがライブネス解析の結果を効率的に表現するために使用するデータ構造です。スタックフレームやヒープオブジェクト内のどのポインタがライブであるかを示すビットの集合です。このビットマップは、GCがメモリをスキャンする際に、どのメモリ領域をたどるべきかを判断するために使用されます。
    • スタックとヒープ:
      • スタック: 関数呼び出しやローカル変数が一時的に格納されるメモリ領域です。関数の呼び出しとリターンに伴って自動的に割り当て・解放されます。
      • ヒープ: プログラムの実行中に動的にメモリを割り当てる領域です。GCによって管理されます。Goでは、エスケープ解析によって、スタックに収まらない変数や、関数のスコープを越えて参照される可能性のある変数がヒープに割り当てられます。

このコミットの核心は、addrtakenフラグが正しく設定され、それがfn->dclを通じてGCのライブネスビットマップ作成に反映されるようにすることです。

技術的詳細

このコミットの技術的な核心は、Goコンパイラが内部でNodeオブジェクトをどのように管理し、そのライフサイクルを通じて情報がどのように伝播するかという点にあります。

問題の根源は、src/cmd/gc/gen.cにあるtemp関数にありました。この関数は、コンパイラが一時的な変数や内部的な計算結果を表現するために新しいNodeを作成する際に使用されます。歴史的な理由により、temp関数は、新しく作成されたNodeオブジェクトの「コピー」を返していました。ここで言う「コピー」とは、メモリ上の異なるアドレスに存在するが、初期状態ではオリジナルのNodeと同じ内容を持つ別のNodeオブジェクトを指します。

コンパイラの分析パス(例えば、typecheck.cで行われるアドレス取得のチェック)は、このtemp関数が返したコピーされたNodeに対してaddrtaken = 1のような情報を記録していました。しかし、fn->dcl(現在の関数で宣言されたノードのリスト)には、このコピーではなく、temp関数が内部で最初に作成した「オリジナルのNode」が保持されていました。

このため、コピーされたノードに記録されたaddrtaken情報は、オリジナルのノードには伝播せず、結果としてfn->dclを通じてGCのライブネスビットマップが作成される際に、その変数がアドレス取得済みであるという情報が失われていました。GCは、アドレスが取得されていない(スタックに割り当てられるべき)変数として誤って判断し、その変数がまだライブであるにもかかわらず、スタックフレームが解放されると同時にそのメモリを再利用可能と見なしてしまう可能性がありました。

この修正は、この不整合を解消するために、以下の変更を導入しています。

  1. temp関数の変更 (src/cmd/gc/gen.c):

    • temp関数が、作成したNodeのコピーではなく、そのNodeの「オリジナル」を指すn->origを返すように変更されました。Node構造体には、そのノードが別のノードのコピーである場合に、オリジナルのノードを指すorigフィールドが存在します。この変更により、tempが返すNode*は常に「正規の(canonical)」ノード、つまりfn->dclに保持されているものと同じ実体を参照するようになります。
  2. staticassign関数の変更 (src/cmd/gc/sinit.c):

    • staticassign関数は、静的な割り当て(例えば、グローバル変数の初期化)を処理する際に、一時的なNodeを作成することがあります。この関数内でnod(OXXX, N, N)によって新しいノードaが作成された後、*a = n1;n1の内容がaにコピーされます。この直後にa->orig = a;という行が追加されました。これは、aが「完全に独立したコピー」であり、それ自身がオリジナルであることを明示的に示すためのものです。これにより、aが後で別のノードのorigフィールドとして参照される際に、正しい実体を指すことが保証されます。
  3. typecheck関数の変更 (src/cmd/gc/typecheck.c):

    • checklvalue関数内でaddrtakenフラグを設定するロジックに、新しいチェックが追加されました。
    • if(l->orig != l && l->op == ONAME): これは、現在処理しているノードlが、それ自身のオリジナルではない(つまり、コピーである)にもかかわらず、ONAME(名前付き変数)である場合に真となります。
    • fatal("found non-orig name node %N", l);: 上記の条件が真の場合、コンパイラは致命的なエラーを発生させます。これは、ONAMEのような重要なノードは常にそのオリジナルであるべきであり、コピーされたノードに対してaddrtakenのような重要な情報が設定されるべきではないという、コンパイラの内部的な不整合を検出するためのガードレールです。このチェックにより、将来的に同様の問題が発生するのを防ぎます。

これらの変更により、コンパイラ内部でNodeがコピーされる場合でも、addrtakenのような重要な分析情報が常にオリジナルのNodeに正しく関連付けられるようになり、GCのライブネス解析が正確に行われることが保証されます。

コアとなるコードの変更箇所

src/cmd/gc/gen.c

--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -939,5 +939,5 @@ temp(Type *t)
 	n = nod(OXXX, N, N);
 	tempname(n, t);
 	n->sym->def->used = 1;
-	return n;
+	return n->orig;
 }

src/cmd/gc/sinit.c

--- a/src/cmd/gc/sinit.c
+++ b/src/cmd/gc/sinit.c
@@ -468,6 +468,7 @@ staticassign(Node *l, Node *r, NodeList **out)
 			else {
 				a = nod(OXXX, N, N);
 				*a = n1;
+				a->orig = a; // completely separate copy
 				if(!staticassign(a, e->expr, out))
 					*out = list(*out, nod(OAS, a, e->expr));
 			}

src/cmd/gc/typecheck.c

--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -723,6 +723,8 @@ reswitch:
 		checklvalue(n->left, "take the address of");
 		for(l=n->left; l->op == ODOT; l=l->left)
 			l->addrtaken = 1;
+		if(l->orig != l && l->op == ONAME)
+			fatal("found non-orig name node %N", l);
 		l->addrtaken = 1;
 		defaultlit(&n->left, T);
 		l = n->left;

test/fixedbugs/issue7083.go (新規追加)

// run

package main

import "runtime/debug"

func f(m map[int]*string, i int) {
	s := ""
	m[i] = &s
}

func main() {
	debug.SetGCPercent(0)
	m := map[int]*string{}
	for i := 0; i < 40; i++ {
		f(m, i)
		if len(*m[i]) != 0 {
			println("bad length", i, m[i], len(*m[i]))
			panic("bad length")
		}
	}
}

コアとなるコードの解説

  1. src/cmd/gc/gen.ctemp 関数:

    • 変更前: return n;
    • 変更後: return n->orig;
    • この変更が最も重要です。temp関数は、コンパイラが一時的な変数や内部的な計算結果を表すために新しいNodeを作成する際に呼び出されます。以前は、新しく作成されたNodeオブジェクトnそのものを返していました。しかし、Nodeがコピーされるような状況では、nがオリジナルのノードのコピーである可能性がありました。
    • n->origは、nがコピーである場合に、そのオリジナルのノードを指すポインタです。もしnがそれ自身がオリジナルであれば、n->orign自身を指します。この変更により、temp関数は常に「正規の(canonical)」Node*、つまりfn->dclに保持されているものと同じ実体を参照するポインタを返すようになります。これにより、その後の分析でaddrtakenなどのフラグが設定された際に、正しいNodeオブジェクトに情報が記録されるようになります。
  2. src/cmd/gc/sinit.cstaticassign 関数:

    • 追加行: a->orig = a; // completely separate copy
    • staticassign関数は、静的な割り当て(例えば、グローバル変数の初期化)を処理する際に、一時的なNodeを作成することがあります。ここでa = nod(OXXX, N, N);によって新しいノードaが作成され、*a = n1;n1の内容がaにコピーされます。
    • 追加されたa->orig = a;は、このaが他のどのノードのコピーでもなく、それ自身が独立したオリジナルであることを明示的に示しています。これは、temp関数の変更と合わせて、Nodeorigフィールドのセマンティクスをより厳密に保つためのものです。これにより、コンパイラがNodeの「オリジナル」を追跡する際の整合性が向上します。
  3. src/cmd/gc/typecheck.ctypecheck 関数内:

    • 追加されたチェック:
      if(l->orig != l && l->op == ONAME)
          fatal("found non-orig name node %N", l);
      
    • このコードは、addrtakenフラグを設定する直前に追加されました。lは現在処理しているNodeです。
    • l->orig != l: これは、lがそれ自身のオリジナルではない、つまりlが別のノードのコピーであることを意味します。
    • l->op == ONAME: これは、lが名前付き変数(例えば、ローカル変数やパラメータ)を表すノードであることを意味します。
    • このif文は、「もしlが名前付き変数であるにもかかわらず、それがオリジナルのノードではなくコピーであるならば、致命的なエラーを発生させる」というガードレールです。名前付き変数のような重要なノードは、常にそのオリジナルであるべきであり、コピーされたノードに対してaddrtakenのような重要な情報が設定されるべきではありません。このチェックは、コンパイラ内部の不整合を早期に検出し、将来的に同様の問題が発生するのを防ぐためのものです。
  4. test/fixedbugs/issue7083.go:

    • このテストケースは、修正されたバグを再現するために作成されました。
    • debug.SetGCPercent(0): ガベージコレクションを無効にします。これにより、GCがメモリを解放するタイミングを制御し、バグの再現性を高めます。
    • func f(m map[int]*string, i int): この関数内で、ローカル変数s(空文字列)が宣言され、そのアドレス&sがマップmに格納されます。
    • 問題は、sが関数fのスタックフレーム上に割り当てられるべきローカル変数であるにもかかわらず、そのアドレスがマップに格納されることで、sがエスケープ解析によってヒープに割り当てられるべきであるとコンパイラが判断する必要がある点です。
    • もしaddrtakenフラグが正しく設定されず、コンパイラがsがスタック変数であると誤って判断した場合、f関数がリターンするとsのメモリ領域は解放されたと見なされます。しかし、マップにはそのアドレスが残っているため、main関数で*m[i]を dereference しようとすると、既に解放されたメモリにアクセスすることになり、クラッシュや不正なデータ(len(*m[i])が0でない)を読み取る可能性があります。
    • テストでは、len(*m[i]) != 0をチェックすることで、この問題が修正されたことを検証しています。修正後、sは正しくヒープにエスケープされ、マップから参照されている間はGCによって解放されないため、len(*m[i])は常に0(空文字列の長さ)になります。

これらの変更は、Goコンパイラの内部的なNode管理の堅牢性を高め、特にエスケープ解析とGCのライブネス解析の正確性を保証するために不可欠でした。

関連リンク

参考にした情報源リンク

  • Goコンパイラのソースコード (src/cmd/gc ディレクトリ)
  • Go言語のガベージコレクションに関するドキュメントや解説記事 (一般的な知識として)
  • Goのエスケープ解析に関する情報 (一般的な知識として)
  • Goのruntime/debugパッケージのドキュメント
  • Goのmapの動作に関する情報 (一般的な知識として)