[Go开源工具] go-optioner:轻松生成函数选项模式代码

前言

最近在进行重构代码时,我遇到了一个问题:在使用函数选项模式来构造一个结构体时,由于该结构体字段过多,我需要手动编写大量的设置选项函数的代码。这样的工作既繁琐又容易出错。

为了解决这个问题,我开始在 github 上面寻找能够根据结构体的定义自动生成函数选项模式代码的工具,尽管找到了几个相关工具,但并没有完全符合我的要求。因此我决定自己动手,开发了 go-optioner 工具,并将其推荐给大家使用。

工具链接: github.com/chenmingyon...

欢迎 Star ,如果有任何问题或提供功能的改进方案,欢迎提交 IssuesPull Request(PR)

go-optioner

go-optioner 是一个在 Go 代码中生成函数选项模式代码的工具。该工具可以根据给定的结构定义自动生成相应的选项代码。

安装

  • 1、go install github.com/chenmingyong0423/go-optioner/cmd/optioner@latest

  • 2、执行 optioner 命令检查是否安装成功

    go 复制代码
    > 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

如果你安装成功了,但是提示 optioner 命令找不到,请确认是否已将 $GOPATH/bin 添加到环境变量中。

使用教程

你可以直接使用 optioner 命令生成对应结构体的 functional options 代码,也可以使用 go generate 命令进行批量生成。

optioner 命令

  • 1、首先,你需要创建一个包含需要生成函数选项模式代码的结构体的 Go 文件。在结构体字段中,您可以使用 opt 标签来控制是否为 NewXXX() 函数的必传参数和生成相应的函数。

    go 复制代码
    package example
    
    type User struct {
        Name   string `opt:"-"`
        Age    int
        Gender string
    }

如果字段定义了 opt 标签,并且值为 -,则它将作为 NewXXX 函数的必要参数,并且不会生成该字段的 WithXXX 函数。

注意:必须声明 package

  • 2、在包含结构体定义的文件目录下,执行 optioner -type XXX 命令,其中 XXX 是结构体的名称。执行命令之后,optioner 工具会根据结构体定义生成相应的函数选项模式代码。内容如下所示:

    go 复制代码
    // Generated by optioner -type User; 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 func(*User)
    
    func NewUser(name string, opts ...UserOption) *User {
        user := &User{
            Name: name,
        }
    
        for _, opt := range opts {
            opt(user)
        }
    
        return user
    }
    
    func WithAge(age int) UserOption {
        return func(user *User) {
            user.Age = age
        }
    }
    
    func WithGender(gender string) UserOption {
        return func(user *User) {
            user.Gender = gender
        }
    }

optioner 工具将会生成一个名为 opt_xxx_gen.go 的文件,其中 xxx 是结构体的名称,例如 opt_user_gen.go。该文件包含生成的函数选项代码,用于初始化结构体和设置结构体字段的值。

go generate 命令

请注意,在执行 go generate 命令之前,确保您的项目已经初始化 Go Modules 或正确设置了 GOPATH,并且您的项目结构符合 Go ModulesGOPATH 的要求。

  • 1、首先,你需要创建一个包含需要生成函数选项模式代码的结构体的 Go 文件。在结构体定义之上,你需要添加 //go:generate optioner -type XXX 的注释,其中 XXX 是结构体的名称。这样工具就能根据参数生成相应的代码。在结构体字段中,您可以使用 opt 标签来控制是否为 NewXXX() 函数的必传参数和生成相应的函数。

    go 复制代码
    package example
    
    //go:generate optioner -type User
    type User struct {
        Name   string `opt:"-"`
        Age    int
        Gender string
    }

如果字段定义了 opt 标签,并且值为 -,则它将作为 NewXXX 函数的必要参数,并且不会生成该字段的 WithXXX 函数。

注意:必须声明 package

  • 2、在包含结构体定义的文件目录下,执行 go generate 命令,这将调用 optioner 工具并根据结构体定义生成相应的函数选项模式代码。内容如下所示:

    go 复制代码
    // Generated by optioner -type User; 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 func(*User)
    
    func NewUser(name string, opts ...UserOption) *User {
        user := &User{
            Name: name,
        }
    
        for _, opt := range opts {
            opt(user)
        }
    
        return user
    }
    
    func WithAge(age int) UserOption {
        return func(user *User) {
            user.Age = age
        }
    }
    
    func WithGender(gender string) UserOption {
        return func(user *User) {
            user.Gender = gender
        }
    }

optioner 工具将会生成一个名为 opt_xxx_gen.go 的文件,其中 xxx 是结构体的名称,例如 opt_user_gen.go。该文件包含生成的函数选项代码,用于初始化结构体和设置结构体字段的值。

小结

在本文中,我介绍了 go-opioner 开源工具的安装和使用,它能够根据结构体的定义,自动生成函数选项模式的代码。它让我们告别繁琐的构造函数编写和修改,让代码编写过程更加高效和愉悦。

希望各位开发者能够踊跃给 go-optioner 点予星标(Star),以示支持和认可。您的支持是持续改进和优化工具的动力。同时,也欢迎各位提交 IssuesPull Request(PR),为 go-optioner 提出宝贵的意见和贡献更好的功能和改进。

工具链接: github.com/chenmingyon...

相关推荐
探索宇宙真理.9 分钟前
WordPress AI Engine信息泄露漏洞 | CVE-2025-11749 复现&研究
人工智能·经验分享·开源·安全漏洞
shoubepatien20 分钟前
JAVA -- 12
java·后端·intellij-idea
木木一直在哭泣29 分钟前
Spring 里的过滤器(Filter)和拦截器(Interceptor)到底啥区别?
后端
源码获取_wx:Fegn089537 分钟前
基于springboot + vue物业管理系统
java·开发语言·vue.js·spring boot·后端·spring·课程设计
無量37 分钟前
MySQL事务与锁机制深度剖析
后端·mysql
無量38 分钟前
MySQL索引设计与优化实战
后端·mysql
木木一直在哭泣1 小时前
CAS 一篇讲清:原理、Java 用法,以及线上可用的订单状态机幂等方案
后端
王中阳Go1 小时前
我辅导400+学员拿Go Offer后发现:突破年薪50W,常离不开这10个实战技巧
后端·面试·go
Tortoise1 小时前
OpenTortoise:开箱即用的Java调用LLM中间件,一站式解决配置、调用、成本监控和智能记忆
后端
AI猫站长1 小时前
商汤科技孵化“大晓机器人”,联合创始人王晓刚亲自挂帅,推出开源世界模型3.0与具身超级大脑模组,万亿具身智能赛道再迎重量级玩家,行业竞争格局生变
科技·机器人·开源