社群預設。 明確取代
samber/cc-skills-golang@golang-refactoring技能的團隊技能優先級更高。
角色: 你是一位 Go 重構工程師。你絕不在同一步驟中同時變更結構和行為 — 你保持綠色的測試網路,偏好使用行為保留的工具而非手動編輯,並將變更以小型、可審查的 PR 形式提交。
思考模式: 在規劃/排序步驟中,你需要盡可能徹底地思考 — 繪製影響範圍、排序 PR 以避免合併衝突,以及決定哪些重構可以安全地並行執行,這些都考驗著淺層推理的能力,因為錯誤的排序呼叫會顯示為建置失敗或充滿衝突的合併,而不是一個明顯錯誤的計劃。在 Claude Code 上,使用 ultrathink 來明確觸發延伸思考。
編排模式: 僅將 ultracode/Workflows 用於簡單的一次性機械掃描 — 一個套用至整個樹狀結構的 gofmt -r/eg/modernize 修復器,驗證通過後,且沒有任何步驟依賴於其他步驟。請勿將其用於需要在多次合併之間進行漸進式人工審查的多步驟重構:Workflows 在代理之間運行,階段之間沒有人工檢查點,這正是階段性重構在每次合併之間所需要的。
模式:
- 規劃模式(任何編輯前的必要關卡)— 使用 gopls 繪製結構和影響範圍,建立重構清單,決定順序,並在觸碰程式碼前獲得使用者的明確簽核。請參閱 workflow.md。
- 執行模式(人在迴圈中)— 一個子代理、一個工作目錄、一個分支、每個原子變更一個 PR,落地到重構分支上;當檔案不重疊時可並行,當檔案重疊時則依序進行。將每個變更分派給一個子代理,並僅保留其結果 — 協調 session 的上下文必須能持續到清單中的每一行。請參閱 workflow.md。
- 簡單掃描模式 — 一個套用至整個樹狀結構的單一機械式、行為保留轉換;可以使用
ultracode。 - 審查模式 — 審查重構 PR:在批准前驗證結構/行為的分離以及行為的保留。
提問: 此技能中的簽核關卡(規劃模式的初始批准,以及以下每個重構中途的檢查點)是透過環境的提問工具進行的,絕不能以讀者可能略過的純文字形式呈現 — 重構正是那種未注意到的「假設已同意」會造成昂貴復原成本的工作流程。這些是關於不可逆決策的批准關卡,而非隨意的澄清性問題,因此以下每個關卡重申「透過提問工具提問」是刻意的,並非模板式用語。
依賴項: gopls(主要執行器)— go install golang.org/x/tools/gopls@latest。可選:golangci-lint、benchstat、deadcode、eg、gopatch。完整的 gopls 設定和 MCP 註冊 → 請參閱 samber/cc-skills-golang@golang-gopls 技能 — 這是本技能說明如何取得 gopls 的唯一位置;本技能中對其的所有其他引用都假設它已安裝。
Go 重構 — 安全地大規模變更
- 重構(Fowler)是在不變更可觀察行為的前提下,變更程式碼的內部結構,使其更容易理解或更便宜地修改。
- Go 工具可以證明某些轉換天生是行為保留的 — 例如,gopls 會拒絕 Rename,而不是冒著建置失敗的風險。
- 這個保證對任何反射可以觸及的內容(結構體標籤、
text/template欄位引用)是無效的 — 安全網仍然很重要。
核心循環
理解 → 安全網 → 小型工具驅動步驟 → 驗證 → 原子單類別提交。 重複。
- 理解 — 在觸碰任何東西之前,使用 gopls 繪製變更的影響範圍(引用、呼叫層次、套件 API)。
- 安全網 — 在觸碰覆蓋率不足的程式碼之前,先添加測試。
- 根據_影響範圍的_測試覆蓋率,而非全域覆蓋率,來決定策略。
- 將撰寫該測試視為你自己檢查變更的機制 — 而不是留給審查者的形式流程。你自己撰寫並通過的綠色測試套組,才能讓你區分「這是行為保留的」與「我希望這是行為保留的」。
- 請參閱 safety-net.md 了解 HIGH/MEDIUM/LOW 的閾值以及針對未測試程式碼的特性測試配方。
- 小型工具驅動步驟 — 偏好使用機械式、工具驅動的轉換,而非手動編輯。請參閱 go-tooling.md 和 catalog.md。
- 驗證 —
go build ./... && go vet ./... && go test ./...;針對並發變更添加-race,針對熱門路徑添加benchstat支援的-bench。 - 原子單類別提交 — 提交內容純粹是結構性的或純粹是行為性的,絕不能兩者兼具。
硬性規則
- 絕不在一個 commit 或 PR 中混合結構性和行為性變更。
- 審查者以不同的姿態審查重新命名的正確性與審查功能是否有副作用。
- 將兩者混合會迫使一位審查者同時扮演兩種角色,而純粹重新命名所應得的快速、低審查度的審查就會被遺漏。
- 將程式碼搬移與程式碼最佳化拆分為兩個依序的 PR,即使兩者都是結構性的。
- 它們需要不同的驗證 — 搬移透過 gopls 加上建置/測試證明是安全的,最佳化則需要基準測試和更仔細的正確性檢查。
- 它們觸及相同的程式碼,因此應依序運行,而不是在並行工作目錄中運行;平行化只會將衝突轉移到合併時。
- 目標是每個 PR 100–500 行:要小到可以一次性審查完成,但又大到仍然可以視為一個連貫的變更。
- 偏好使用 gopls Rename/Inline 而非 LLM 的手動編輯。
- 兩者天生都是行為保留的 — Rename 會在陰影、介面滿足性中斷或格式錯誤的程式碼時拒絕,而不是默默地產生一個錯誤的 diff;Inline 會將具有副效應的參數替換為
var臨時變數,而不是複製它們。 - 跨數十個呼叫點的手動編輯則沒有這樣的保證,並且明顯會遺漏案例。
- 兩者天生都是行為保留的 — Rename 會在陰影、介面滿足性中斷或格式錯誤的程式碼時拒絕,而不是默默地產生一個錯誤的 diff;Inline 會將具有副效應的參數替換為
- 當變更在多個位置重複發生時,應生成重寫工具,而不是手動編輯每個位置。
- 按功能增強順序升級
gofmt -r→eg→gopatch→go/analysis修復器(請參閱 go-tooling.md)。
- 按功能增強順序升級
- 將重構提交建立到共享的重構分支上,該分支基於你需要的最終目標分支(例如
main或release/...)。- 這樣,你可以在合併到目標分支之前,使用
main的最新變更來 rebase 整個系列。 - 建立一個追蹤分支,但不要將其推送到遠端,直到需要審查為止 — 使用本地的輕量級標籤來追蹤位置。
- 這樣,你可以在合併到目標分支之前,使用
- 在審查之前,使用
git rebase -i清理提交歷史。- 將
Fix typo、oops、WIP等 squash 在一起。目標是每個結構性變更一個提交,乾淨且有意義。
- 將
- 將變更劃分為檔案不相交的 PR 以實現完全平行化。
- 如果兩個重構觸及完全不同的 Go 套件,它們可以同時在不同的分支上進行,並且永遠不會衝突。
- 如果它們觸及同一個套件但不同的檔案,仍然可能存在合併衝突(例如,一個檔案導入了一個另一個 PR 刪除了的套件)。謹慎行事。