mcpField
G
go-functional-options

go-functional-options

github.com/cxuu开发1861.2k 次安装19 周前更新
代码仓库

关于 go-functional-options

介绍 Go 函数式选项模式的开发技能,用于配置构造函数和公共 API。帮助开发者判断何时采用选项、如何组织实现,以及何时配置结构体更简单。

主要功能

  1. 01选择函数式选项的判断依据
  2. 02Option 接口与内部结构模式
  3. 03With* 构造函数指导
  4. 04与配置结构体的比较
  5. 05测试与文档方面的考量

适用场景

  1. 01为构造函数配置可选参数
  2. 02设计可能增加选项的 API
  3. 03在选项与配置结构体间做选择

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/cxuu/golang-skills --skill go-functional-options

安装后在 Claude Code 中输入/go-functional-options确认已加载。

附带文件references/OPTIONS-VS-STRUCTS.md

详细介绍

函数式选项模式

函数式选项是一种模式:声明一个不透明的 Option 类型,用于在内部结构体中记录信息。构造函数接受可变数量的此类选项,并应用它们来配置结果。

资源路由

  • references/OPTIONS-VS-STRUCTS.md - 在选择配置结构体还是函数式选项、实现完整的基于接口的选项模式,或评估混合构造函数 API 时阅读。

适用场景

在以下情况下使用函数式选项:

  • 构造函数或公共 API 有 3 个或更多可选参数
  • 可扩展的 API 可能会随时间增加新选项
  • 调用方体验简洁很重要(无需传入默认值)

模式

核心组件
  1. 未导出的 options 结构体 - 保存所有配置
  2. 导出的 Option 接口 - 带有未导出的 apply 方法
  3. 选项类型 - 实现该接口
  4. With* 构造函数 - 创建选项
Option 接口
type Option interface {
    apply(*options)
}

未导出的 apply 方法可确保只有此包中的选项才能使用。

对比:函数式选项与配置结构体

方面函数式选项配置结构体
可扩展性添加新的 With* 函数添加新字段(可能造成破坏性变更)
默认值内置于构造函数中使用零值或单独设置默认值
调用方体验只需指定不同之处必须构造完整的结构体
可测试性可比较选项比较结构体
复杂度样板代码更多设置更简单

优先选择配置结构体的情况:选项少于 3 个、选项很少变化、通常会同时指定所有选项,或仅用于内部 API。

为什么不使用闭包?

相比仅使用闭包的选项,接口方案更受推荐,原因如下:

  1. 可测试性 - 可在测试和模拟中比较选项
  2. 可调试性 - 选项可以实现 fmt.Stringer
  3. 灵活性 - 选项可以实现其他接口
  4. 可见性 - 选项类型会显示在文档中

快速参考

// 1. Unexported options struct with defaults
type options struct {
    field1 Type1
    field2 Type2
}

// 2. Exported Option interface, unexported method
type Option interface {
    apply(*options)
}

// 3. Option type + apply + With* constructor
type field1Option Type1

func (o field1Option) apply(opts *options) { opts.field1 = Type1(o) }
func WithField1(v Type1) Option            { return field1Option(v) }

// 4. Constructor applies options over defaults
func New(required string, opts ...Option) (*Thing, error) {
    o := options{field1: defaultField1, field2: defaultField2}
    for _, opt := range opts {
        opt.apply(&o)
    }
    // ...
}
检查清单
  • options 结构体未导出
  • Option 接口具有未导出的 apply 方法
  • 每个选项都有一个 With* 构造函数
  • 在应用选项前设置默认值
  • 必需参数与 ...Option 分开

相关技能

  • 接口设计:设计 Option 接口或在接口与闭包方案之间进行选择时,参阅 go-interfaces
  • 命名约定:为 With* 构造函数、选项类型或未导出的 options 结构体命名时,参阅 go-naming
  • 函数设计:在文件中组织构造函数或格式化可变参数签名时,参阅 go-functions
  • 文档:为 Option 类型、With* 函数或构造函数行为编写文档时,参阅 go-documentation
外部资源

评论

支持 Markdown