上級のGoエラー 40問
8種類のエラーを、それぞれ複数パターンずつ収録しています。
- 値レシーバのメソッドは呼び出し元の値を変更しない値レシーバで定義したメソッドは、レシーバのコピーに対して操作を行います。メソッド内でフィールドを変更しても、呼び出し元の元の変数には反映されません。
- ポインタレシーバのメソッドしか無い型は値ではinterfaceを満たさないポインタレシーバで定義したメソッドは、その型の値そのもの(非ポインタ)のメソッドセットには含まれません。値をそのままinterface型の変数に代入しようとするとコンパイルエラーになります。
- スライスやマップを含む構造体は == で比較できないスライスやマップ、関数値をフィールドに持つ構造体は比較不可能な型として扱われ、==演算子で比較しようとするとコンパイルエラーになります。
- recoverは同じgoroutine内のpanicしか捕まえないrecoverはそれを呼び出したgoroutine内で発生したpanicしか回復できません。別のgoroutine内でdeferとrecoverを仕込んでも、他のgoroutineのpanicは捕まえられずプログラム全体がクラッシュします。
- 埋め込み構造体のメソッドが外側の同名メソッドにシャドーイングされる構造体に別の構造体を埋め込むと、埋め込み側のメソッドが昇格して呼び出せるようになります。しかし外側の構造体が同名のメソッドを定義していると、そちらが優先され埋め込み側のメソッドは隠れてしまいます。
- does not satisfy(ジェネリクスの制約違反)の原因と直し方ジェネリック関数の型パラメータには制約(constraint)を指定できます。制約が要求する演算(比較や算術演算など)をサポートしない型を渡すと、コンパイルエラーになります。
- deferの引数はdefer文を実行した時点の値で評価されるdefer文に渡した関数呼び出しの引数は、実際に関数が実行される(関数の終了時)タイミングではなく、defer文自体が実行された時点で評価され確定します。
- 名前付き戻り値が内側のブロックで:=によりシャドーイングされる名前付き戻り値の変数と同じ名前をif文などの内側のブロックで:=を使って再宣言すると、それは別の新しいローカル変数になります。裸のreturnではブロック外の元の名前付き戻り値の値が返され、内側で設定した値は反映されません。