千家信息网

Golang函数式选项模式怎么实现

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容主要讲解"Golang函数式选项模式怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Golang函数式选项模式怎么实现"吧!概览最近阅读源码
千家信息网最后更新 2026年11月03日Golang函数式选项模式怎么实现

本篇内容主要讲解"Golang函数式选项模式怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Golang函数式选项模式怎么实现"吧!

概览

最近阅读源码的时候看到一段不错的代码,但是当时却不是非常理解为什么这么写。
我们先来看一下源代码:

type User struct {        ID     string        Name   string        Age    int        Email  string        Phone  string        Gender string}type Option func(*User)func WithAge(age int) Option {        return func(u *User) {                u.Age = age        }}func WithEmail(email string) Option {        return func(u *User) {                u.Email = email        }}func WithPhone(phone string) Option {        return func(u *User) {                u.Phone = phone        }}func WithGender(gender string) Option {        return func(u *User) {                u.Gender = gender        }}func NewUser(id string, name string, options ...func(*User)) (*User, error) {        user := User{                ID:     id,                Name:   name,                Age:    0,                Email:  "",                Phone:  "",                Gender: "female",        }        for _, option := range options {                option(&user)        }        //...        return &user, nil}func main() {        user, err := NewUser("1", "Ada", WithAge(18), WithPhone("123456"))        if err != nil {                fmt.Printf("NewUser: err:%v", err)        }        fmt.Printf("NewUser Success")}

当时呢,也不是很明白 NewUser 这个构造函数为什么要这么写,后来查看了资料才知道了这是一种设计模式-函数式选项(functional options)模式。

什么是函数式选项模式,为什么要这么写,这个编程模式解决了什么问题呢?

其实就是为了解决动态灵活的配置不同的参数的问题。

假如我们有一个需求:
在网站注册账号,有很多可选的选项,可填可不填。会根据你填的信息初始化你的 User 对象。

重载函数

如果你有 C++ 或者 Java 的编程基础,你的第一反应应该是函数重载。

但是因为 Golang 语言不像 C++ 一样支持重载函数,所以,你得用不同的函数名来应对不同的配置选项。

像这样:

func NewUserDefault(id string, name string) (*User, error) {  return &User{ID: id, Name: name}, nil}func NewUserWithPhone(id string, name string, phone string) (*User, error) {  return &User{ID: id, Name: name, Phone: phone}, nil}func NewUserWithEmail(id string, name string, email string) (*User, error) {  return &User{ID: id, Name: name, Email: email}, nil}

如果一共只有两三个参数的情况下,比较简单,但是更多的选项的组合就代码看起来很乱了。

配置化

这个时候我们可能会想到,配置化。
把所有可选的参数放到一个Config的struct中。

type Config struct {    Age    int    Email  string    Phone  string    Gender string}

然后把Config放到User的struct中。

type User struct {    ID   string    Name string    Conf *Config}

于是,我们只需要一个 NewUser() 的函数了,在使用前需要构造 Config 对象。

func NewUser(id string, name string, conf *Config) (*User, error) {    //...}//Using the default configuratrionuser, _ := NewUser("1", "Ada", nil)conf := Config{Age:18, Phone: "123456"}user2, _ := NewUser("2", "Bob", &conf)

这段代码看起来算是不错了,很多时候我使用的一些开源库也是这么写的。通过引入一个Config对象来解决多个参数的组合的问题。

Builder模式

有些经常使用Java的同学会想到Builder模式。

于是就可以以如下的方式来使用了:

user := new(UserBuilder).Create("1", "Ada").  age(18).  phone("123456").  gender("female").  Build()

需要引入一个抽象的UserBuilder对象,来包装User对象,最终Build一个User对象返回。

函数式选项模式

函数式选项模式 首先需要定义一个函数类型:

type Option func(*User)

然后,我们定义一组返回函数的函数:

func WithAge(age int) Option {        return func(u *User) {                u.Age = age        }}func WithEmail(email string) Option {        return func(u *User) {                u.Email = email        }}func WithPhone(phone string) Option {        return func(u *User) {                u.Phone = phone        }}func WithGender(gender string) Option {        return func(u *User) {                u.Gender = gender        }}

这个模式和Builder模式的区别是,Builder模式返回的是 * User 对象,Functional Options 返回的是函数类型 func(* User)。

上面这组代码传入一个参数,然后返回一个函数,返回的这个函数会设置自己的 User 参数。

这样我们就方便在 NewUser 里面统一初始化。循环对我们的函数类型执行调用操作。 option(&user)

func NewUser(id string, name string, options ...func(*User)) (*User, error) {        user := User{                ID:     id,                Name:   name,                Age:    0,                Email:  "",                Phone:  "",                Gender: "female",        }        for _, option := range options {                option(&user)        }        //...        return &user, nil}

调用方式如下:

user1, err := NewUser("1", "Ada")user2, err := NewUser("2", "Bob", WithPhone("123456"), WithGender("male"))

这个看起来比较整洁和优雅,对外的接口只有一个NewUser。

相比于Builder模式,不需要引入一个Builder对象。

对比配置化的模式,也不需要引入一个新的Config。

到此,相信大家对"Golang函数式选项模式怎么实现"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

函数 模式 对象 参数 配置 代码 不同 时候 类型 问题 不错 内容 只有 方式 更多 网站 C++ 学习 组合 编程 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技的发展 科技服务与互联网 平安科技 互联网 华中科技大学互联网 奇酷互联网络科技公司 菲比寻常互联网科技 左右互联网络科技 恒生科技互联网指数分析 阿里巴巴算科技企业还是互联网 成都互联网科技公司工作好不好 速维有品互联网信息科技(苏州)有限公司 开一家科技互联网公司需要多少钱 本届互联网博览会上的黑科技 南博望互联网科技有限公司 恒生互联网科技业指数调整周期 互联网第三次科技革命特征 中国互联网有什么科技 互联网硬科技公司 互联网科技和医药行业 现代科技的标志之一的互联网 科技互联网产品 重庆互联网络科技 互联网公司 科技公司 卓越科技互联网 招聘 互联网科技公司的市场部门 温州喔噻互联网科技有限公司 互联网校园科技培训 广州有谷有贝互联网科技有限公司 广州智享互联网科技 保山互联网科技靠谱吗
0