go-optioner
是一个在 Go 代码中生成函数选项模式代码的工具。该工具可以根据给定的结构定义自动生成相应的选项代码。
English | 中文简体
- 1、
go install github.com/chenmingyong0423/go-optioner/cmd/optioner@latest
- 2、执行
optioner
命令检查是否安装成功
> optioner
optioner is a tool for generating functional options pattern.
Usage:
optioner [flags]
Flags:
-type <struct name>
-output <output path>, default: srcDir/opt_xxx_gen.go
-with_prefix <the prefix of the With{filed_name} function>, default is With{filed_name}.If specified, such as User, it will generate WithUser{filed_name}
-mode <the file writing mode>, default: write
there are two available modes:
- write(Write/Overwrite): Overwrites or creates a new file.
- append (Append): Adds to the end of the file.
如果你安装成功了,但是提示 optioner
命令找不到,请确认是否已将 $GOPATH/bin
添加到环境变量中。
使用 Optioner
时,你可以通过以下参数定制其行为:
-type
: 指定目标结构体的名称,这是一个必需参数。-output
: 设置生成代码的输出文件路径。这是一个可选参数,默认生成的文件名格式为opt_{StructName}_gen.go
,其中{StructName}
是结构体的名称,文件位于当前目录下。-with_prefix
:设置 With{filed_name} 函数的前缀。这是一个可选参数,默认值为 With{filed_name}。如果指定了前缀,例如 User,则生成的函数名将变为 WithUser{filed_name}。-mode
: 定义文件写入方式,接受的值有:write
(写入/覆盖):如果文件已存在,将其覆盖;如果文件不存在,创建新文件。append
(追加):将内容追加到现有文件的末尾。
你可以直接使用 optioner
命令生成对应结构体的 functional options
代码,也可以使用 go generate
进行批量生成。
-
1、首先,假定您已经准备好一个
Go
文件,其中包含了您希望生成函数选项模式代码的结构体。在该结构体的字段上,您可以利用opt
标签来标记哪些字段应作为New{FieldName}
函数的必要参数。package example type User[T any, R any] struct { Name string `opt:"-"` NecGenericFiled T `opt:"-"` Age int Gender string GenericFiled R }
如果结构体字段使用了
opt
标签并将其值设置为-
,则该字段成为New{FieldName}
函数的必需参数,同时不会为该字段生成With{FieldName}
函数。注意:必须声明
package
。 -
2、在包含结构体定义的文件所在目录下,执行
optioner -type {StructName}
命令,将{StructName}
替换为实际的结构体名称,例如optioner -type User
。此命令执行后,optioner
工具会根据结构体定义自动创建默认的opt_user_gen.go
文件,并在其中生成函数选项模式代码。生成的代码结构如下所示:// Generated by [optioner] command-line tool; DO NOT EDIT // If you have any questions, please create issues and submit contributions at: // https://github.com/chenmingyong0423/go-optioner package example type UserOption[T any, R any] func(*User[T, R]) func NewUser[T any, R any](name string, necGenericFiled T, opts ...UserOption[T, R]) *User[T, R] { user := &User[T, R]{ Name: name, NecGenericFiled: necGenericFiled, } for _, opt := range opts { opt(user) } return user } func WithAge[T any, R any](age int) UserOption[T, R] { return func(user *User[T, R]) { user.Age = age } } func WithGender[T any, R any](gender string) UserOption[T, R] { return func(user *User[T, R]) { user.Gender = gender } } func WithGenericFiled[T any, R any](genericFiled R) UserOption[T, R] { return func(user *User[T, R]) { user.GenericFiled = genericFiled } }
如果需要自定义生成代码的输出文件路径,可以通过指定
output
和mode
参数进行配置。
请注意,在执行 go generate
命令之前,确保您的项目已经初始化 Go Modules
或正确设置了 GOPATH
,并且您的项目结构符合 Go Modules
或 GOPATH
的要求。
-
1、首先,假定您已经准备好一个
Go
文件,其中包含了您希望生成函数选项模式代码的结构体。在该结构体定义之上,添加注释//go:generate optioner -type {StructName}
,并把{StructName}
替换为您的实际结构体名称。例如,使用//go:generate optioner -type User
来为User
结构体生成代码。在该结构体的字段上,您可以利用opt
标签来标记哪些字段应作为New{FieldName}
函数的必要参数。package example //go:generate optioner -type User type User[T any, R any] struct { Name string `opt:"-"` NecGenericFiled T `opt:"-"` Age int Gender string GenericFiled R }
如果结构体字段使用了
opt
标签并将其值设置为-
,则该字段成为New{FieldName}
函数的必需参数,同时不会为该字段生成With{FieldName}
函数。注意:必须声明
package
。 -
2、在包含结构体定义的文件所在目录下,运行
go generate
命令,这个命令将触发optioner
工具,并根据结构体定义自动创建默认的opt_user_gen.go
文件,同时在该文件中生成函数选项模式的代码。生成的代码结构如下所示:// Generated by [optioner] command-line tool; DO NOT EDIT // If you have any questions, please create issues and submit contributions at: // https://github.com/chenmingyong0423/go-optioner package example type UserOption[T any, R any] func(*User[T, R]) func NewUser[T any, R any](name string, necGenericFiled T, opts ...UserOption[T, R]) *User[T, R] { user := &User[T, R]{ Name: name, NecGenericFiled: necGenericFiled, } for _, opt := range opts { opt(user) } return user } func WithAge[T any, R any](age int) UserOption[T, R] { return func(user *User[T, R]) { user.Age = age } } func WithGender[T any, R any](gender string) UserOption[T, R] { return func(user *User[T, R]) { user.Gender = gender } } func WithGenericFiled[T any, R any](genericFiled R) UserOption[T, R] { return func(user *User[T, R]) { user.GenericFiled = genericFiled } }
如果需要自定义生成代码的输出文件路径,可以修改
//go:generate optioner -type User
的内容,通过指定output
和mode
参数进行配置。
我非常欢迎其他人对这个项目做出贡献!如果你有任何问题、改进建议或发现了 bug,请通过提交 issue 来与我们交流。如果你想提交代码贡献,请按照以下步骤:
1、Fork
这个仓库并克隆到本地。
2、创建一个新的分支:git checkout -b feature/your-feature
。
3、在你的分支上进行修改或添加新功能。
4、提交你的更改:git commit -m "描述你的修改"
5、推送到你的 Fork
仓库:git push origin feature/your-feature
6、创建 Pull
请求,将你的更改合并到主仓库。
请确保您的代码遵循项目的编码风格并通过测试。
这个项目遵循 Apache License 许可。
如果你有任何问题或意见,可以通过以下方式联系我们:
- 邮件:[[email protected]]
- GitHub:[https://github.com/chenmingyong0423]