golang-safety
nilパニック・サイレントなデータ破損・実行時バグを防ぐための防御的なGolangコーディングを支援します。ポインタ・インターフェース・マップ・スライス・チャネルといったnil発生リスクの高い型、数値変換、リソースのライフサイクル管理(ループ内でのdeferなど)、防御的コピーが絡むコードの作成・レビュー時に活用できます。nilパニック・appendのエイリアシング・マップへの並行アクセス・浮動小数点の比較・ゼロ値設計に関する疑問にも対応します。
description の原文を見る
Defensive Golang coding to prevent panics, silent data corruption, and subtle runtime bugs. Use whenever writing or reviewing Go code that involves nil-prone types (pointers, interfaces, maps, slices, channels), numeric conversions, resource lifecycle (defer in loops), or defensive copying. Also triggers on questions about nil panics, append aliasing, map concurrent access, float comparison, or zero-value design.
SKILL.md 本文
Persona: You are a defensive Go engineer. You treat every untested assumption about nil, capacity, and numeric range as a latent crash waiting to happen.
Go Safety: Correctness & Defensive Coding
プログラマのミスを防止します — 通常の(対立的でない)コード内のバグ、パニック、サイレント データ破損を防ぎます。セキュリティは攻撃者に対処します。安全性は自分たち自身に対処します。
ベストプラクティスの概要
- 型セットが判明している場合は
anyよりもジェネリクスを選択 — コンパイラが実行時パニックの代わりにミスマッチをキャッチします - 型アサーションでは常にコンマOKを使用 — ベアアサーションはミスマッチ時にパニックします
- インターフェース内の型付きnil ポインタは
== nilではない — 型記述子により nil以外になります - nil マップへの書き込みはパニック — 使用前に常に初期化してください
appendはバッキング配列を再利用する可能性 — 容量が許せば両方のスライスがメモリを共有し、サイレントに相互破損します- エクスポート関数から防御的コピーを返す — そうしないと呼び出し元があなたの内部を変異させます
deferは関数終了で実行、ループイテレーションではない — ループボディを関数に抽出します- 整数型変換はサイレントに切り詰められる —
int64からint32へのラップは エラーなしで発生します - 浮動小数点演算は正確ではない — イプシロン比較または
math/bigを使用してください - 有用なゼロ値を設計 — nil マップフィールドは最初の書き込みでパニック。遅延初期化を使用してください
- 遅延初期化には
sync.Onceを使用 — 並行実行下でも正確に1回を保証します
Nil セーフティ
Nil関連のパニックは Go における最も一般的なクラッシュです。
nil インターフェーストラップ
インターフェースは (type, value) を保存します。インターフェースが nil であるのは両方が nil の場合のみです。型付きnil ポインタを返すと型記述子が設定され、nil以外になります:
// ✗ Dangerous — interface{type: *MyHandler, value: nil} is not == nil
func getHandler() http.Handler {
var h *MyHandler // nil pointer
if !enabled {
return h // interface{type: *MyHandler, value: nil} != nil
}
return h
}
// ✓ Good — return nil explicitly
func getHandler() http.Handler {
if !enabled {
return nil // interface{type: nil, value: nil} == nil
}
return &MyHandler{}
}
nil マップ、スライス、チャネルの動作
| Type | nil から読み込み | nil への書き込み | nil の Len/Cap | nil をrange |
|---|---|---|---|---|
| Map | ゼロ値 | panic | 0 | 0 イテレーション |
| Slice | panic (index) | panic (index) | 0 | 0 イテレーション |
| Channel | 永遠にブロック | 永遠にブロック | 0 | 永遠にブロック |
// ✗ Bad — nil map panics on write
var m map[string]int
m["key"] = 1
// ✓ Good — initialize or lazy-init in methods
m := make(map[string]int)
func (r *Registry) Add(name string, val int) {
if r.items == nil { r.items = make(map[string]int) }
r.items[name] = val
}
詳細は Nil Safety Deep Dive を参照。nil レシーバー、ジェネリクス内の nil、nil インターフェースパフォーマンスについて説明しています。
スライス&マップセーフティ
スライスエイリアシング — append トラップ
append は容量が許せばバッキング配列を再利用します。両方のスライスがメモリを共有します:
// ✗ Dangerous — a and b share backing array
a := make([]int, 3, 5)
b := append(a, 4)
b[0] = 99 // also modifies a[0]
// ✓ Good — full slice expression forces new allocation
b := append(a[:len(a):len(a)], 4)
マップの並行アクセス
マップは並行でアクセスしてはいけません — samber/cc-skills-golang@golang-concurrency を参照して同期プリミティブを確認してください。
詳細は Slice and Map Deep Dive を参照。range のピットフォール、サブスライスメモリ保持、slices.Clone/maps.Clone について説明しています。
数値セーフティ
暗黙の型変換はサイレントに切り詰められる
// ✗ Bad — silently wraps around if val > math.MaxInt32 (3B becomes -1.29B)
var val int64 = 3_000_000_000
i32 := int32(val) // -1294967296 (silent wraparound)
// ✓ Good — check before converting
if val > math.MaxInt32 || val < math.MinInt32 {
return fmt.Errorf("value %d overflows int32", val)
}
i32 := int32(val)
浮動小数点比較
// ✗ Bad — floating point arithmetic is not exact
0.1+0.2 == 0.3 // false
// ✓ Good — use epsilon comparison
const epsilon = 1e-9
math.Abs((0.1+0.2)-0.3) < epsilon // true
ゼロで除算
整数のゼロ除算はパニックします。浮動小数点のゼロ除算は +Inf、-Inf、または NaN を生成します。
func avg(total, count int) (int, error) {
if count == 0 {
return 0, errors.New("division by zero")
}
return total / count, nil
}
セキュリティ脆弱性としての整数オーバーフロー については、samber/cc-skills-golang@golang-security スキルセクションを参照してください。
リソースセーフティ
ループ内の defer — リソース蓄積
defer は関数終了時に実行され、ループイテレーションではありません。関数が戻るまでリソースが蓄積します:
// ✗ Bad — all files stay open until function returns
for _, path := range paths {
f, _ := os.Open(path)
defer f.Close() // deferred until function exits
process(f)
}
// ✓ Good — extract to function so defer runs per iteration
for _, path := range paths {
if err := processOne(path); err != nil { return err }
}
func processOne(path string) error {
f, err := os.Open(path)
if err != nil { return err }
defer f.Close()
return process(f)
}
ゴルーチンリーク
samber/cc-skills-golang@golang-concurrency を参照してゴルーチンライフサイクルとリーク防止を確認してください。
イミュータビリティ&防御的コピー
エクスポート関数がスライス/マップを返す場合は防御的コピーを返すべきです。
構造体の内部保護
// ✗ Bad — exported slice field, anyone can mutate
type Config struct {
Hosts []string
}
// ✓ Good — unexported field with accessor returning a copy
type Config struct {
hosts []string
}
func (c *Config) Hosts() []string {
return slices.Clone(c.hosts)
}
初期化セーフティ
ゼロ値設計
var x MyType が安全になるように型を設計 — 「初期化忘れ」バグを防ぎます:
var mu sync.Mutex // ✓ usable at zero value
var buf bytes.Buffer // ✓ usable at zero value
// ✗ Bad — nil map panics on write
type Cache struct { data map[string]any }
遅延初期化に sync.Once を使用
type DB struct {
once sync.Once
conn *sql.DB
}
func (db *DB) connection() *sql.DB {
db.once.Do(func() {
db.conn, _ = sql.Open("postgres", connStr)
})
return db.conn
}
init() 関数のピットフォール
samber/cc-skills-golang@golang-design-patterns を参照して、明示的なコンストラクタを優先する理由を確認してください。
リンターで強制
多くのセーフティピットフォールは errcheck、forcetypeassert、nilerr、govet、staticcheck などのリンターで自動的にキャッチされます。samber/cc-skills-golang@golang-lint スキルで設定と使用方法を確認してください。
クロスリファレンス
samber/cc-skills-golang@golang-concurrencyスキルを参照 — 並行アクセスパターンと同期プリミティブについてsamber/cc-skills-golang@golang-data-structuresスキルを参照 — スライス/マップの内部、容量成長、container/ パッケージについてsamber/cc-skills-golang@golang-error-handlingスキルを参照 — nil エラーインターフェーストラップについてsamber/cc-skills-golang@golang-securityスキルを参照 — セキュリティ関連のセーフティ問題(メモリセーフティ、整数オーバーフロー)についてsamber/cc-skills-golang@golang-troubleshootingスキルを参照 — パニックとレース条件のデバッグについて
一般的なミス
| ミス | 修正 |
|---|---|
ベア型アサーション v := x.(T) | 型ミスマッチでパニック、プログラムがクラッシュ。v, ok := x.(T) で優雅に処理 |
| インターフェース関数で型付き nil を返す | インターフェースが (type, nil) を保持、これは != nil。nil の場合は型なしの nil を返す |
| nil マップへの書き込み | nil マップはバッキングストレージなし — 書き込みはパニック。make(map[K]V) で初期化または遅延初期化 |
append は常にコピーすると仮定 | 容量が許せば両方のスライスがバッキング配列を共有。s[:len(s):len(s)] でコピーを強制 |
ループ内の defer | defer は関数終了時に実行、ループイテレーションではない — リソースが蓄積。ボディを別関数に抽出 |
境界チェックなしの int64 から int32 | 値はサイレントにラップ (3B → -1.29B)。先に math.MaxInt32/math.MinInt32 と照合 |
浮動小数点を == で比較 | IEEE 754 表現は正確ではない (0.1+0.2 != 0.3)。math.Abs(a-b) < epsilon で比較 |
| ゼロチェックなしの整数除算 | 整数のゼロ除算はパニック。除算前に if divisor == 0 で保護 |
| 内部スライス/マップ参照を返す | 呼び出し元が共有バッキング配列を通じて構造体の内部を変異させられる。防御的コピーを返す |
オーダリング仮定で複数の init() | ファイル間の init() 実行順序は未指定。samber/cc-skills-golang@golang-design-patterns を参照 — 明示的なコンストラクタを使用 |
| nil チャネルで永遠にブロック | nil チャネルは送受信両方でブロック。使用前に常に初期化 |
クロスリファレンス
samber/cc-skills-golang@golang-continuous-integrationスキルを参照 — これらのガイドラインを使用した CI での自動AI駆動コードレビューについて
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- samber
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/samber/cc-skills-golang / ライセンス: MIT
関連スキル
hugging-face-trackio
Trackioを使用してMLトレーニング実験を追跡・可視化できます。トレーニング中のメトリクスログ記録(Python API)、トレーニング診断のアラート発火、ログされたメトリクスの取得・分析(CLI)が必要な場合に活用してください。リアルタイムダッシュボード表示、Webhookを使用したアラート、HF Space同期、自動化向けのJSON出力に対応しています。
btc-bottom-model
ビットコインのサイクルタイミングモデルで、加重スコアリングシステムを搭載しています。日次パルス(4指標、32ポイント)とウィークリー構造(9指標、68ポイント)の2カテゴリーにわたる13の指標を追跡し、0~100のマーケットヒートスコアを算出します。ETFフロー、ファンディングレート、ロング/ショート比率、恐怖・貪欲指数、LTH-MVRV、NUPL、SOPR(LTH+STH)、LTH供給率、移動平均倍率(365日MA、200週MA)、週次RSI、出来高トレンドに対応します。市場サイクル全体を通じて買いと売りの両方の推奨を提供します。ビットコインの底値拾い、BTCサイクルポジション、買い時・売り時、オンチェーン指標、MVRV、NUPL、SOPR、LTH動向、ETFの流出入、ファンディングレート、恐怖指数、ビットコインが過熱状態か、マイナーコスト、暗号資産市場のセンチメント、BTCのポジションサイジング、「今ビットコインを買うべきか」「BTCが天井をつけているか」「オンチェーン指標は何を示しているか」といった質問の際にこのスキルを活用します。
protein_solubility_optimization
タンパク質の溶解性最適化 - タンパク質の溶解性を最適化します。タンパク質の特性を計算し、溶解性と親水性を予測し、有効な変異を提案します。タンパク質配列の特性計算、タンパク質機能の予測、親水性計算、ゼロショット配列予測を含むタンパク質エンジニアリング業務に使用できます。3つのSCPサーバーから4つのツールを統合しています。
research-lookup
Parallel Chat APIまたはPerplexity sonar-pro-searchを使用して、最新の研究情報を検索できます。学術論文の検索にも対応しています。クエリは自動的に最適なバックエンドにルーティングされるため、論文の検索、研究データの収集、科学情報の検証に活用できます。
tree-formatting
ggtree(R)またはiTOL(ウェブ)を使用して、系統樹の可視化とフォーマットを行います。系統樹を図として描画する際、ツリーレイアウトの選択、分類学に基づく枝やラベルの色付け、クレードの折りたたみ、サポート値の表示、またはツリーへのオーバーレイ追加が必要な場合に使用してください。系統推定(protein-phylogenyスキルを使用)やドメイン注釈(今後の独立したスキル)には使用しないでください。
querying-indonesian-gov-data
インドネシア政府の50以上のAPIとデータソースに接続できます。BPJPH(ハラール認証)、BOM(食品安全)、OJK(金融適正性)、BPS(統計)、BMKG(気象・地震)、インドネシア中央銀行(為替レート)、IDX(株式)、CKAN公開データポータル、pasal.id(第三者法MCP)に対応しています。インドネシア政府データを活用したアプリ開発、.go.idウェブサイトのスクレイピング、ハラール認証の確認、企業の法的適正性の検証、金融機関ステータスの照会、またはインドネシアMCPサーバーへの接続時に使用できます。CSRF処理、CKAN API使用方法、IP制限回避など、すぐに実行可能なPythonパターンを含んでいます。