Go语言中的Options模式

Go 语言的“刻意贫穷“:为什么宁可写 30 行选项模式,也拒绝默认参数? Go 拒绝默认参数不是"技术无能",而是"工程智慧"隐式行为在大规模协作中成本极高显式表达虽然代码多,但可维护性强选项模式是 Go 生态的"最佳实践"被 gRPC、etcd、Kubernetes 等广泛采用类型安全、向后兼容、自文档化"30 行代码"是"好的复杂"这 30 行是投资,不是负担换来的是清晰的 API、可维护的代码Go 语言的"刻意贫穷",本质上是一种工程克制。好的设计不是添加更多特性,而是勇敢地拒绝诱惑。 阅读详情

Go语言中的Options模式:提升代码的可扩展性与灵活性

在开发中,我们经常需要为某些函数或方法提供多个可选的参数(如配置项)。如果这些参数较多,并且某些参数在某些情况下可能不被使用,传递多个参数会变得不够优雅,尤其是当参数类型较复杂时。为了解决这个问题,Go语言的Options模式(有时也叫配置模式)提供了一种灵活的方式。

1. Options模式概述

Options模式是一种通过使用函数作为参数的方式来传递配置项的模式。它能够简化函数签名,避免了多个参数传递的混乱,并且使得参数的可选性变得非常清晰。

该模式的核心思想是:

  • 使用一个结构体(通常用于存储配置信息)和一组函数(选项函数)来配置结构体的字段。
  • 通过可变参数(...Option)将这些选项函数传递给需要配置的对象或方法。
  • 选项函数修改结构体中的字段,从而完成自定义配置。

2. Options模式的实现方式

2.1 定义结构体和选项函数

首先,我们定义一个包含可选参数的结构体,之后编写一组函数来配置这个结构体。

package main

import (
	"fmt"
)

// 定义配置结构体
type Config struct {
	Host   string
	Port   int
	APIKey string
}

// 定义 Options 类型,这个类型是一个函数,接收一个 *Config 类型的指针
type Option func(*Config)

// 创建用于设置Host的选项函数
func WithHost(host string) Option {
	return func(c *Config) {
		c.Host = host
	}
}

// 创建用于设置Port的选项函数
func WithPort(port int) Option {
	return func(c *Config) {
		c.Port = port
	}
}

// 创建用于设置APIKey的选项函数
func WithAPIKey(apiKey string) Option {
	return func(c *Config) {
		c.APIKey = apiKey
	}
}
2.2 初始化函数

然后,我们创建一个初始化函数,接受多个选项函数,并根据传递的选项函数设置 Config 结构体的字段。

// 初始化函数,接受可变参数 Option,用于配置 Config
func NewConfig(options ...Option) *Config {
	// 设置默认值
	config := &Config{
		Host:   "localhost",
		Port:   8080,
		APIKey: "",
	}

	// 遍历所有的选项函数并应用它们
	for _, option := range options {
		option(config)
	}

	return config
}
2.3 使用Options模式

最后,在主函数中,我们使用选项函数来初始化配置,并设置我们需要的配置项。

func main() {
	// 使用选项函数来设置配置信息
	config := NewConfig(
		WithHost("example.com"),
		WithPort(9000),
		WithAPIKey("my-api-key"),
	)

	// 输出最终的配置
	fmt.Printf("Config: %+v\n", config)
}

3. Options模式的优点

3.1 可扩展性

使用Options模式,我们可以灵活地添加新选项,而不会影响现有代码。比如,添加一个新的配置项(如Timeout)时,我们只需要编写一个新的选项函数,并在NewConfig函数中应用它,而不会修改函数签名或原有逻辑。

3.2 可选参数的清晰性

Options模式避免了传递过多复杂的参数,特别是当某些参数是可选的时。使用选项函数,你可以只配置需要的选项,而将其他选项保持为默认值。这种方式让函数签名变得更加简洁,代码可读性更强。

3.3 便于维护和修改

在传统的函数签名中,随着参数数量的增加,函数可能会变得冗长且难以维护。通过Options模式,你可以避免这些问题。需要更改默认行为时,只需修改相应的选项函数,而无需修改调用函数的位置或函数签名。

3.4 解耦合

Options模式有助于减少函数与具体实现的耦合。你可以将不同的配置选项封装成函数,使得配置的应用和业务逻辑分离,增强代码的灵活性。

4. 实际案例:数据库配置

在很多实际应用中,数据库配置常常需要使用Options模式。我们可以通过Options模式来初始化一个数据库连接配置,并为数据库连接提供不同的选项。

4.1 定义数据库配置结构体
type DBConfig struct {
	Host     string
	Port     int
	User     string
	Password string
	Database string
}
4.2 定义选项函数
// 设置主机
func WithHost(host string) Option {
	return func(c *DBConfig) {
		c.Host = host
	}
}

// 设置端口
func WithPort(port int) Option {
	return func(c *DBConfig) {
		c.Port = port
	}
}

// 设置用户名
func WithUser(user string) Option {
	return func(c *DBConfig) {
		c.User = user
	}
}

// 设置密码
func WithPassword(password string) Option {
	return func(c *DBConfig) {
		c.Password = password
	}
}

// 设置数据库名称
func WithDatabase(database string) Option {
	return func(c *DBConfig) {
		c.Database = database
	}
}
4.3 初始化数据库配置
func NewDBConfig(options ...Option) *DBConfig {
	// 默认配置
	config := &DBConfig{
		Host:     "localhost",
		Port:     3306,
		User:     "root",
		Password: "",
		Database: "testdb",
	}

	// 应用所有选项
	for _, option := range options {
		option(config)
	}

	return config
}
4.4 使用数据库配置
func main() {
	// 创建数据库配置
	dbConfig := NewDBConfig(
		WithHost("127.0.0.1"),
		WithPort(5432),
		WithUser("admin"),
		WithPassword("password"),
		WithDatabase("production"),
	)

	// 输出最终配置
	fmt.Printf("DBConfig: %+v\n", dbConfig)
}

5. 常见的应用场景

5.1 HTTP客户端配置

Options模式可以用于配置 HTTP 客户端的参数,如超时设置、代理、重试次数等。

5.2 数据库连接配置

像前面提到的,数据库连接需要灵活的配置项。你可以通过Options模式为连接池配置并传递多个可选参数。

5.3 日志配置

日志系统通常也需要进行复杂的配置。Options模式允许你灵活地设置日志级别、输出格式、日志文件路径等。

6. 总结

Go语言中的Options模式是一种非常实用的设计模式,尤其在需要传递多个可选配置项时。它的优势在于能够让代码更加灵活、清晰、易于维护和扩展。通过将配置项封装为函数,我们可以确保代码解耦,同时保持高度的可读性。

当你的函数或方法有许多可选参数时,Options模式无疑是一个非常优秀的解决方案,能够使你的代码更加优雅和易于管理。

Go函数选项模式:functional options 函数选项模式用函数作为配置项,必填参数显式传,可选参数用With函数按需配置。新加配置项只需要加字段和With函数,现有调用方代码不用改,向后兼容好。选项之间有依赖关系时,让选项函数返回error,在构造函数末尾做整体校验。下一篇我们聊中间件模式,看看洋葱模型怎么组织HTTP处理流程。 阅读详情

相关推荐

Openharmony 命令行工具hdc的获取与安装

OpenHarmony实战:命令行工具hdc安装应用指南_hdc工具-优快云博客t=N7T8。

Devlin_的博客 1万+

一些实用的编程模式 | Options模式

今天开个新系列,讲一些实用的编程模式,每个编程模式学完后,都能马上在实战中应用起来,让我们写出更富表达力、易维护、好扩展、优雅亿点点的代码。这些编程模式的示例我会用Go来演示,但其实这些模...

kevin_tech的博客,微信搜「网管叨bi叨」 663

PostgreSQL隐式类型转换全解析:告别operator does not exist

强类型数据库是现代数据系统的基石,它在带来严谨性的同时,也常常让开发者在类型不匹配报错前束手无策。当一条SQL因bigint与text比较而抛出operator does not exist时,根源往往在于对数据库隐式转换规则的误解。PostgreSQL通过pg_cast系统表将转换划分为隐式、赋值与显式三个级别,并依据操作符解析逻辑决定是否自动提升类型。理解这些机制,不仅能快速定位JOIN、UNION、函数调用等场景下的类型错误,还能帮助开发者合理使用EXPLAIN VERBOSE、pg_typeof等工

weixin_29587015的博客 304

go使用options模式设置参数

Functional Options Pattern(函数式选项模式)可用于传递不同选项配置到方法中。当每次选项参数有变更的时候,可以不改变方法或者接口的参数,这样保证了接口兼容性。使用Options的模式也更利于程序的扩展,所以在众多包中得到了广泛的使用。 ......

程序猿CKeen的专栏 3159

CS231n+assignment2(一)

cs231n作业二详解+代码

qq_56551150的博客 2411

python基于语音识别的智能垃圾分类系统

大家好我是蓝天,混迹在java圈的辛苦码农。今天要和大家聊的是一款《python基于语音识别的智能垃圾分类系统》毕业设计项目。项目源码以及部署相关请联系蓝天,文末附上联系信息。🎈作者:蓝天🎈🎈个人简介:精通 Java、Python、C#、C、C++ 等编程语言,同时对微信小程序、Php 和 Android 等技术也能熟练掌握,可为大家提供全面的技术支持与交流。我拥有丰富的成品 Java、Python、C# 毕业设计项目经验,能够为学生提供各类个性化的开题框架及实际运作方案。🎈。

Chujun123528的博客 660

深入理解Golang中的Options模式

选项模式是一种基于函数参数的设计模式,它允许用户在调用函数时传递一系列选项来自定义函数的行为。在Golang中,选项模式通常通过函数选项(Functional Options)或结构体选项(Struct Options)来实现。

weixin_53623989的博客 2085

Android无线调试:adb tcpip连接实战指南

本文详细介绍了Android无线调试的完整流程,重点讲解如何使用adb tcpip命令通过Wi-Fi连接设备,摆脱数据线束缚。涵盖环境配置、连接实战、稳定性优化及常见问题排查,帮助开发者高效实现无线adb调试,提升工作效率。

pink的博客 721

浅谈Go语言Optional模式和Builder模式

Optional模式和Builder模式都是Go语言中用于对象构建和配置的重要设计模式。Optional模式通过函数选项提供灵活的配置选项,适用于参数较少且相对简单的情况。而Builder模式则通过逐步构建对象并提供多种配置选项,适用于构建复杂对象的情况。在选择使用哪种模式时,应根据具体需求和对象复杂程度进行权衡。

做兴趣使然的Hero 1283

MATLAB锂离子电池伪二维(P2D)模型实现

锂离子电池伪二维(P2D)模型的MATLAB实现。该模型基于Newman等人提出的经典电化学模型,考虑了固液相扩散、电荷守恒和电化学反应动力学。

hie98894的博客 1928

【Godot】构建可维护的游戏工程 —— 项目代码组织结构

本文系统梳理了Godot引擎项目组织原则与架构模式,提出场景中心化、命名规范一致性和资源隔离三大核心原则。推荐按功能模块划分目录结构(如scenes/、entities/、systems/),采用snake_case命名避免跨平台问题,并通过.gdignore优化资源管理。文章详细解析了自包含场景设计、信号驱动解耦等架构技巧,以及团队协作中的版本控制策略,强调通过模块化设计平衡一致性与实用性。最终目标构建清晰可维护的项目结构,使资源定位和功能扩展更加高效。(148字)

qq_40205510的博客 1173

选项模式(Option Pattern)在 Go 语言中的应用

本文介绍了Go语言中的选项模式(Option Pattern),这是一种用于灵活配置复杂结构体的设计模式。选项模式通过使用函数类型作为参数来动态修改对象属性,避免了构造函数重载的问题,并提高了代码的可扩展性和可维护性。文章通过一个Risk结构体的示例详细解释了选项模式的实现方法。此外,文章还探讨了选项模式的优点。最后,文章强调了选项模式在实际开发中的应用价值,并鼓励读者在项目中合理应用此模式以提升代码质量。

tatasix的博客 1217

基于Python的军事装备信息爬虫实战:Scrapy+Playwright+智能反反爬技术

本文将详细介绍如何使用Python构建一个高效的军事装备信息爬虫系统。我们将从基础的HTTP请求开始,逐步深入到使用Scrapy框架、Playwright浏览器自动化以及最新的反反爬技术。文章包含完整的代码实现、性能优化策略以及数据处理方案,旨在为读者提供一个全面的军事信息爬取解决方案。关键词:Python爬虫、军事装备、Scrapy、Playwright、反反爬。

2201_76125261的博客 1155

ECC 中 Go 编程模式规则详解:从 .cursor/rules/golang-patterns.md 看 Cursor 规则、多端同步与 golang-patterns 技能链

本文以 ECC 仓库中 [golang-patterns.md](https://link.gitcode.com/i/4aea01401cc2ecb1fb95aa479de98602) 这条 Cursor 规则文件为主体,完整解读它如何通过 `globs` 触发机制为 `*.go`、`go.mod`、`go.sum` 文件注入 Go 惯用模式约束,并深入展开它所编码的三个核心设计模式(Funct

gitblog_00365的博客 249

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

一些实用的 Go 编程模式 | Options模式

今天开个新系列,讲一些实用的编程模式,每个编程模式学完后,都能马上在实战中应用起来,让我们写出更富表达力、易维护、好扩展、优雅亿点点的代码。这些编程模式的示例我会用Go来演示,但其实这些模...

EDDYCJY的博客 635

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

JetBrains Mono 等宽字体配置指南:连字、20 个样式集与变量字体一次讲清

凌晨的 diff 里,你把 `0` 读成了 `O`、把 `1` 和 `l` 来回确认三遍——问题不在眼睛,在字体。JetBrains Mono 是一款免费开源(OFL-1.1)的等宽字体,专为写代码设计:拉高小写字母、区分易混符号、内置连字与 20 个样式集。 [![JetBrains Mono 等宽字体字符集总览:拉丁、希腊、西里尔与数学符号](https://raw.gitcode.com/

gitblog_00299的博客 203

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

从多套大模型密钥到统一出口:New API 网关的完整落地指南

手里同时攥着 OpenAI、Claude、Gemini 几家大模型的 API 密钥时,麻烦是真实的:每家接口格式不一样,账单各算各的,谁调了多少、花了多少钱,翻遍后台也未必理得清。把这些上游收拢到一个统一出口,就是 **New AI** 这类 AI 网关要解决的问题——用 New API 做**大模型统一 API 网关**,一个入口调遍各家模型,路由、权限、计费、用量统计都在这一个系统里完成。你之

gitblog_00648的博客 351

go: Functional Options Pattern

本文展示了Go语言中函数式选项模式在珠宝业务配置管理中的应用。通过定义JewelryBusinessConfig结构体包含原料采购、设计制图、加工生产等全业务流程配置项,采用函数式选项模式实现灵活配置。核心实现包括: 定义Option类型作为配置函数 为各业务模块(原料、设计、生产等)创建选项函数(如SetMaterialStandard()、EnableLuxuryPackaging()) 通过CreateConfig工厂函数组合选项 应用场景演示: 标准门店使用默认配置 高端品牌启用定制设计、奢华包装等

Geovin Du Dream Park 182

选项模式(option)

选项模式(option) Option模式的专业术语为:Functional Options Pattern(函数式选项模式) Option模式为golang的开发者提供了将一个函数的参数设置为可选的功能,也就是说我们可以选择参数中的某几个,并且可以按任意顺序传入参数。 比如针对特殊场景需要不同参数的情况,C++可以直接用重载来写出任意个同名函数,在任意场景调用的时候使用同一个函数名即可;但同样情况下,在golang中我们就必须在不同的场景使用不同的函数,并且参数传递方式可能不同的人写出来是不同的样子,这

Go的全部 5574

Go进阶之长参数函数

介绍了Go语言中变长参数函数的使用方法和应用场景。主要内容包括:1)变长参数函数的基本语法和使用限制,如"...T"类型参数必须是最后一个参数;2)通过变长参数模拟函数重载和实现可选参数功能;3)使用功能选项模式实现灵活的参数配置,相比直接暴露参数或使用结构体封装,功能选项模式更具扩展性和灵活性。文章通过fmt和log包的源码示例展示了变长参数的实际应用,并提供了多种实现参数配置的方案比较。

不愿言弃-念何的博客 703

【go语言规范】 使用函数式选项 Functional Options 模式处理可选配置

这是 Go 语言中最推荐的配置模式之一,特别适合那些有很多可选配置项的情况。详细代码转载go语言经典100错。

qq_32641095的博客 674

ECC 规则体系中的 Go 模式:Functional Options、小接口与依赖注入实战指南

> 本篇技术指南以 ECC 仓库中 [docs/ja-JP/rules/golang/patterns.md](https://link.gitcode.com/i/95b992be203596faae2df2b844eca731)(及其英文原版 [rules/golang/patterns.md](https://link.gitcode.com/i/731dbcf4a554af9ebf77f5

gitblog_00491的博客 131

Go设计模式之:函数式选项模式(Functional Options)

需求分析: 假设现在一个对象的一些特性在初始化的时候,一般是有个默认值的。比如在我国的公安部门在为一些人员登记信息的时候,这些人员的默认国籍大部分都会是中国,所以公安工作人员在录入信息的时候系统自动默认录入人员是中国人,除非必要否则并不需要修改,这样减少了公安工作人员的工作量。再比如学校里的学生的犯罪前科都是无的,这一栏默认无就行。 但是Go语言并没有提供默认参数,一旦一个对象有很多属性(这些属性...

林小默 2010

Uber Go 风格指南:Functional Options 函数式选项模式完整实战解析

本文基于 [Uber Go Style Guide](https://link.gitcode.com/i/b29143b7347c0e92645e42a702b51a5b) 仓库中的 [Functional Options 一节](https://link.gitcode.com/i/b29143b7347c0e92645e42a702b51a5b) 展开,系统讲解函数式选项(Functiona

gitblog_00811的博客 998

go tcp 设置超时_GO 编程模式系列(三):FUNCTIONAL OPTIONS

原文作者:陈皓(左耳朵耗子)内容出处:https://coolshell.cn/articles/21146.html在本篇文章中,我们来讨论一下Functional Options这个编程模式。这是一个函数式编程的应用案例,编程技巧也很好,是目前在Go语言中最流行的一种编程模式。但是,在我们正式讨论这个模式之前,我们需要先来看看要解决什么样的问题。本文是全系列中第3 / 9篇:Go编程...

weixin_31302909的博客 193

golang functional options,优雅的初始化对象实例

当我们定义了一个对象时,一般会创建一个方法方便外部初始化一个实例。如下面的例子: type Client struct { timeout int64 dialFunc func() error healthCheck func() bool } func NewClient(timeout int64, dialFunc func() error, healthChec...

liyunlonghere 4168
上一篇: .golangci.yml文件配置
下一篇: Docker容器原理和启动策略
Cxzzzzzzzzzz
博客等级 码龄4年 229粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值