← ClaudeAtlas

go-expertlisted

Go 코드를 작성·리뷰·리팩터링하거나 에러 처리, 동시성, 테스트, net/http 서버, go:embed 를 다룰 때 사용한다. Go 1.22+ 기준.
LeeYudok/doksam-skills · ★ 10 · Web & Frontend · score 77
Install: claude install-skill LeeYudok/doksam-skills
# go-expert Go 코드가 대상이다. SQL·스키마는 `sqlite-expert`/`db-expert`, 프론트 산출물 내장의 빌드 순서는 `frontend-build` 가 맡는다. 이 문서는 **일반론을 적지 않는다.** 판단이 갈리는 지점, 자주 틀리는 곳, 최근 버전에서 바뀐 것만 담는다. ## 1. 에러 - **감싸서 올린다.** `fmt.Errorf("%s 열기 실패: %w", path, err)` — `%w` 여야 `errors.Is`/`errors.As` 가 통한다. `%v` 로 감싸면 사슬이 끊긴다. - **호출부가 분기해야 하는 실패는 센티널로 노출한다.** `var ErrNotFound = errors.New(...)`. 문자열 비교로 분기하지 않는다. - 메시지는 소문자로 시작하고 마침표를 붙이지 않는다. 한국어 메시지도 문장부호 없이 짧게. - **로그와 반환을 동시에 하지 않는다.** 둘 다 하면 같은 실패가 여러 번 기록된다. 최상위(핸들러·main)에서 한 번만 기록한다. - `panic` 은 프로그래머 오류에만. 입력이 잘못된 것은 에러다. ```go if errors.Is(err, chatdb.ErrNotFound) { ... } // 분기 var perr *fs.PathError if errors.As(err, &perr) { ... } // 타입 정보가 필요할 때 ``` ## 2. 동시성 — 필요할 때만 goroutine 을 띄우기 전에 답한다: **누가 이걸 멈추는가? 결과는 누가 받는가?** 답이 없으면 만들지 않는다. - **goroutine 의 수명은 호출부가 통제한다.** `context.Context` 를 첫 인자로 받고, 종료 신호를 존중한다. 구조체 필드에 context 를 넣지 않는다. - 채널로 소유권을 옮기거나, 뮤텍스로 공유를 보호하거나 — **둘을 섞지 않는다.** - `sync.WaitGroup` 은 `Add` 를 goroutine **밖에서** 부른다. 안에서 부르면 경합이다. - 루프 변수 캡처는 Go 1.22부터 반복마다 새 변수라 안전하다. **그 이전 버전 코드를 손볼 때는** 여전히 확인한다. - **테스트는 `-race` 로 돌린다.** 동시성 코드를 추가·수정했으면 필수다. ## 3. net/http — Go 1.22+ ServeMux 메서드와 경로 변수를 표준 mux 가 지원한다. 서드파티 라우터를 새로 들이기 전에 이걸로 충분한지 본다. ```go mux.HandleFunc("GET /api/chat/refs/{ref}/rooms", h) mux.HandleFunc("DELETE /api/chat/dbs/{db}", h) // 핸들러에서 ref := r.PathValue("ref") ``` - 더 구체적인 패턴이 우선한다 — `/api/...` 를 등록해두면 `/` 폴백이 삼키지 않는다. - **경로 변수는 디코딩된 값**이다. 파일명·경로로 쓸 거면 반드시 검증한다(§5). - 서버