Skip to content
Back to skills

Go Coding Standards

ASecurity

Use when writing or reviewing Go code — explains harness9 project coding conventions and patterns

  • 141 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 9, 2026
toolsgobashtesting

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add ZhangShenao/harness9 --skill go-coding-standards --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Go Coding Standards?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Go Coding Standards
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/zhangshenao-go-coding-standards/badge)](https://www.skillsdirectory.com/skills/zhangshenao-go-coding-standards)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: go-coding-standards
description: Use when writing or reviewing Go code — explains harness9 project coding conventions and patterns
trigger: write, review, refactor, add, implement
---

# harness9 Go 编码规范

## 命名规范

| 类别 | 规范 | 示例 |
|------|------|------|
| 包名 | 小写、单单词、无下划线 | `engine`、`provider`、`schema` |
| 导出类型/函数 | PascalCase | `AgentEngine`、`NewRegistry` |
| 未导出类型/函数 | camelCase | `mainLoop`、`runLoop` |
| 接口名 | 以 `-er` 后缀为惯例 | `Provider`、`Registry`、`BaseTool` |
| 常量 | PascalCase(导出)或 camelCase(未导出),**不使用全大写** | `RoleSystem`、`maxLogOutputLen` |
| 配置选项函数 | `With` 前缀 | `WithMaxTurns`、`WithToolTimeout` |

## 错误处理

- 显式检查所有 `error` 返回值,**禁止 `_` 忽略**
- 错误消息不以大写字母开头、不以句号结尾
- 使用 `fmt.Errorf("context: %w", err)` 包装错误,保留错误链

```go
// ✅ 正确
result, err := doSomething()
if err != nil {
    return fmt.Errorf("do something: %w", err)
}

// ❌ 错误
result, _ := doSomething()
```

## 构造函数

命名规范:`New` + 类型名

```go
func NewReadFileTool(workDir string) *ReadFileTool {
    return &ReadFileTool{workDir: filepath.Clean(workDir)}
}
```

## 接口定义原则

**接口定义在使用者侧,而非实现者侧。**

```go
// ✅ 正确:Registry 接口定义在 tools 包(使用者侧)
// internal/tools/registry.go
type Registry interface {
    Register(tool BaseTool) error
    GetAvailableTools() []schema.ToolDefinition
    Execute(ctx context.Context, call schema.ToolCall) schema.ToolResult
}

// ❌ 错误:不要在实现所在的包中定义接口
```

## 并发模式

并发工具执行使用预分配切片 + 索引写入,确保结果顺序:

```go
// Go 1.22+ 中 for range 每次迭代已自动创建新绑定,无需手动传参捕获。
// 本项目使用 Go 1.25,以下写法是正确的:
results := make([]schema.ToolResult, len(toolCalls))
var wg sync.WaitGroup
for i, tc := range toolCalls {
    wg.Add(1)
    go func() {
        defer wg.Done()
        toolCtx, cancel := context.WithTimeout(ctx, e.toolTimeout)
        defer cancel()
        results[i] = e.registry.Execute(toolCtx, tc)
    }()
}
wg.Wait()
```

## 添加新工具的步骤

1. 在 `internal/tools/` 下创建 `xxx.go`,实现 `BaseTool` 接口
2. 使用 `safePath()` 校验所有文件路径参数
3. 在 `internal/tools/xxx_test.go` 中添加表驱动测试
4. 在 `cmd/harness9/main.go` 中注册工具

```go
type MyTool struct {
    workDir string
}

func (t *MyTool) Name() string { return "my_tool" }
func (t *MyTool) Definition() schema.ToolDefinition { /* JSON Schema */ }
func (t *MyTool) Execute(ctx context.Context, args json.RawMessage) (string, error) { /* ... */ }
```

## 测试规范

- 使用标准库 `testing` 包,不引入第三方断言库
- 表驱动测试优先
- 运行:`go test ./...`

```go
func TestXxx(t *testing.T) {
    cases := []struct {
        name  string
        input string
        want  string
    }{
        {"normal", "foo", "bar"},
        {"empty", "", ""},
    }
    for _, tc := range cases {
        t.Run(tc.name, func(t *testing.T) {
            got := Xxx(tc.input)
            if got != tc.want {
                t.Errorf("got %q, want %q", got, tc.want)
            }
        })
    }
}
```

## 代码检查

提交前必须通过:

```bash
gofmt -l .        # 无输出表示格式正确
go vet ./...      # 无 warning
go test ./...     # 全部通过
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.