【go】函数类型的作用

Go 语言函数类型的巧妙应用

函数类型在 Go 语言中非常强大,允许将函数作为值进行传递和操作。下面详细介绍函数类型的各种妙用:

1. 回调函数

// 定义一个函数类型
type Callback func(int) int// 接受回调函数的函数
func processData(data []int, callback Callback) []int {result := make([]int, len(data))for i, v := range data {result[i] = callback(v)}return result
}// 使用示例
func main() {numbers := []int{1, 2, 3, 4, 5}// 使用匿名函数作为回调doubled := processData(numbers, func(x int) int {return x * 2})// 使用已定义函数作为回调squared := processData(numbers, square)fmt.Println(doubled)  // [2 4 6 8 10]fmt.Println(squared)  // [1 4 9 16 25]
}func square(x int) int {return x * x
}

2. 策略模式实现

type PaymentStrategy func(amount float64) boolfunc processPayment(amount float64, strategy PaymentStrategy) bool {return strategy(amount)
}// 各种支付策略
func creditCardPayment(amount float64) bool {// 信用卡支付逻辑return true
}func alipayPayment(amount float64) bool {// 支付宝支付逻辑return true
}// 使用示例
func pay(amount float64, paymentMethod string) bool {switch paymentMethod {case "credit":return processPayment(amount, creditCardPayment)case "alipay":return processPayment(amount, alipayPayment)default:return false}
}

3. 装饰器模式

type HttpHandler func(w http.ResponseWriter, r *http.Request)// 日志装饰器
func LoggingDecorator(handler HttpHandler) HttpHandler {return func(w http.ResponseWriter, r *http.Request) {fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)handler(w, r)fmt.Println("Request completed")}
}// 认证装饰器
func AuthDecorator(handler HttpHandler) HttpHandler {return func(w http.ResponseWriter, r *http.Request) {// 检查认证信息if authenticate(r) {handler(w, r)} else {http.Error(w, "Unauthorized", http.StatusUnauthorized)}}
}// 使用装饰器
func main() {http.HandleFunc("/api/data", LoggingDecorator(AuthDecorator(handleData)))http.ListenAndServe(":8080", nil)
}func handleData(w http.ResponseWriter, r *http.Request) {// 业务逻辑
}

4. 函数选项模式

type Server struct {host stringport inttimeout time.DurationmaxConn int
}type ServerOption func(*Server)// 创建Server的选项函数
func WithHost(host string) ServerOption {return func(s *Server) {s.host = host}
}func WithPort(port int) ServerOption {return func(s *Server) {s.port = port}
}func WithTimeout(timeout time.Duration) ServerOption {return func(s *Server) {s.timeout = timeout}
}func WithMaxConn(maxConn int) ServerOption {return func(s *Server) {s.maxConn = maxConn}
}// 创建服务器
func NewServer(options ...ServerOption) *Server {// 设置默认值server := &Server{host:    "localhost",port:    8080,timeout: 30 * time.Second,maxConn: 100,}// 应用所有选项for _, option := range options {option(server)}return server
}// 使用示例
func main() {server := NewServer(WithHost("example.com"),WithPort(9000),WithTimeout(60 * time.Second),)// 使用server...
}

5. 中间件链

type Middleware func(http.Handler) http.Handler// 中间件链
func Chain(middlewares ...Middleware) Middleware {return func(next http.Handler) http.Handler {for i := len(middlewares) - 1; i >= 0; i-- {next = middlewares[i](next)}return next}
}// 使用示例
func main() {handler := http.HandlerFunc(finalHandler)// 创建中间件链chain := Chain(loggingMiddleware,authMiddleware,rateLimitMiddleware,)// 应用中间件链http.Handle("/api", chain(handler))http.ListenAndServe(":8080", nil)
}

6. 延迟执行与钩子函数

type ShutdownHook func()type App struct {shutdownHooks []ShutdownHook
}func (a *App) AddShutdownHook(hook ShutdownHook) {a.shutdownHooks = append(a.shutdownHooks, hook)
}func (a *App) Shutdown() {// 按照注册顺序的相反顺序执行钩子for i := len(a.shutdownHooks) - 1; i >= 0; i-- {a.shutdownHooks[i]()}
}// 使用示例
func main() {app := &App{}// 注册数据库关闭钩子app.AddShutdownHook(func() {fmt.Println("关闭数据库连接")})// 注册文件清理钩子app.AddShutdownHook(func() {fmt.Println("清理临时文件")})// 应用运行...// 关闭应用app.Shutdown()
}

7. 操作集合的函数

type FilterFunc func(int) bool
type MapFunc func(int) int
type ReduceFunc func(int, int) int// 过滤集合
func Filter(nums []int, filter FilterFunc) []int {result := []int{}for _, n := range nums {if filter(n) {result = append(result, n)}}return result
}// 映射集合
func Map(nums []int, mapper MapFunc) []int {result := make([]int, len(nums))for i, n := range nums {result[i] = mapper(n)}return result
}// 归约集合
func Reduce(nums []int, initialValue int, reducer ReduceFunc) int {result := initialValuefor _, n := range nums {result = reducer(result, n)}return result
}// 使用示例
func main() {numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}// 过滤偶数evens := Filter(numbers, func(n int) bool {return n%2 == 0})// 将数字翻倍doubled := Map(evens, func(n int) int {return n * 2})// 求和sum := Reduce(doubled, 0, func(acc, n int) int {return acc + n})fmt.Println("结果:", sum) // 60
}

8. 依赖注入

type UserRepository interface {FindByID(id int) (User, error)
}type UserService struct {repo UserRepository
}func NewUserService(repo UserRepository) *UserService {return &UserService{repo: repo}
}// 测试时可以轻松注入模拟实现
func TestUserService(t *testing.T) {mockRepo := &MockUserRepository{FindByIDFunc: func(id int) (User, error) {return User{ID: id, Name: "测试用户"}, nil},}service := NewUserService(mockRepo)// 测试 service...
}

9. 自定义排序

type Person struct {Name stringAge  int
}type SortBy func(p1, p2 *Person) booltype PersonSorter struct {people []Personless   SortBy
}func (s PersonSorter) Len() int           { return len(s.people) }
func (s PersonSorter) Swap(i, j int)      { s.people[i], s.people[j] = s.people[j], s.people[i] }
func (s PersonSorter) Less(i, j int) bool { return s.less(&s.people[i], &s.people[j]) }// 使用示例
func main() {people := []Person{{"张三", 30},{"李四", 25},{"王五", 35},}// 按年龄排序sort.Sort(PersonSorter{people: people,less: func(p1, p2 *Person) bool {return p1.Age < p2.Age},})fmt.Println("按年龄排序:", people)// 按姓名排序sort.Sort(PersonSorter{people: people,less: func(p1, p2 *Person) bool {return p1.Name < p2.Name},})fmt.Println("按姓名排序:", people)
}

10. 惰性计算

type LazyEval func() interface{}func computeExpensiveValue() LazyEval {computed := falsevar result interface{}return func() interface{} {if !computed {fmt.Println("执行昂贵计算...")// 模拟耗时操作time.Sleep(1 * time.Second)result = 42computed = true}return result}
}// 使用示例
func main() {// 创建惰性计算lazy := computeExpensiveValue()fmt.Println("惰性计算创建后,尚未执行计算")// 调用时才执行实际计算value := lazy()fmt.Println("第一次获取值:", value)// 再次调用不会重复计算value = lazy()fmt.Println("第二次获取值:", value)
}

函数类型使 Go 拥有了函数式编程的部分能力,同时保持了语言的简洁性和性能,这使得它在构建灵活、可测试和可维护的代码时非常有价值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33755.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity屏幕适配——立项时设置

项目类型&#xff1a;2D游戏、竖屏、URP 其他类型&#xff0c;部分原理类似。 1、确定设计分辨率&#xff1a;750*1334 为什么是它&#xff1f; 因为它是 iphone8 的尺寸&#xff0c;宽高比适中。 方便后续适配到真机的 “更长屏” 或 “更宽屏” 2、在场景…

PawSQL for TDSQL:腾讯云TDSQL数据库性能优化全攻略

TDSQL 作为腾讯云推出的分布式数据库&#xff0c;凭借其高扩展性、高可用性和高性能等优势&#xff0c;广泛应用于金融、互联网、政务等领域。随着业务的不断增长和数据量的爆炸式增长&#xff0c;如何优化 TDSQL 数据库的性能&#xff0c;成为众多企业和开发者面临的挑战。本文…

机器学习(七)

一&#xff0c;监督学习和无监督学习聚类的数据集比较&#xff1a; 监督学习&#xff1a; 数据集包括输入的数据和与之对应的标签 无监督学习&#xff1a; 数据集仅含有输入的数据&#xff0c;要求算法自己通过所给的数据集来确定决策边界 二&#xff0c;聚类(Clustering): 聚…

海鲜水产行业wordpress外贸主题

模板采用清新的海洋风格设计&#xff0c;完美契合水产和海鲜行业的特点&#xff0c;让您的网站在众多竞争者中脱颖而出。 高质量的图片展示区域&#xff0c;让您可以展示新鲜捕捞的海鲜产品&#xff0c;吸引客户的注意力。 多功能性&#xff0c;满足业务需求&#xff1a; 模…

调优案例一:堆空间扩容提升吞吐量实战记录

&#x1f4dd; 调优案例一&#xff1a;堆空间扩容提升吞吐量实战记录 &#x1f527; 调优策略&#xff1a;堆空间扩容三部曲 # 原配置&#xff08;30MB堆空间&#xff09; export CATALINA_OPTS"$CATALINA_OPTS -Xms30m -Xmx30m"# 新配置&#xff08;扩容至120MB&am…

【大模型系列】llama.cpp本地运行大模型

上一篇链接: 【大模型系列】使用ollama本地运行千问2.5模型 我们讲了ollama本地运行大模型&#xff0c;这里我们介绍另一种本地运行大模型的方法&#xff1a;llamacpp 软件下载 下载地址&#xff1a;https://github.com/ggml-org/llama.cpp/releases 下载cpu版本的llamacpp&a…

maven之自定义插件

写在前面 在使用maven肯定是离不开插件的&#xff0c;比如执行mvn clean或者时mvn compile其实运行的就是绑定的默认插件。虽然我们一般不需要来自定义插件&#xff0c;但是为了使用的过程中更加的清晰&#xff0c;来尝试自定义插件还是很有必要的&#xff0c;所以本文就一起来…

工程实践:如何使用SU17无人机来实现室内巡检任务

阿木实验室最近发布了科研开发者版本的无人机SU17&#xff0c;该无人机上集成了四目视觉&#xff0c;三维激光雷达&#xff0c;云台吊舱&#xff0c;高算力的机载计算机&#xff0c;是一个非常合适的平台用于室内外巡检场景。同时阿木实验室维护了多个和无人机相关的开源项目。…

【瞎折腾/Dify】使用docker离线部署Dify

文章目录 说在前面安装Docker(外网)获取Dify源码(外网)拉取docker镜像(外网)导出镜像(内网)导入镜像(内网)运行问题 说在前面 外网操作系统&#xff1a;windows内网操作系统&#xff1a;ubuntu外网docker desktop版本&#xff1a;4.29.0外网docker版本&#xff1a;version 26.0…

【Git】配置Git

配置Git 忽略特殊文件 在日常开发中&#xff0c;有些文件不想或不应该提交到远端&#xff0c;如保存数据库密码的配置文件。 在Git工作区的根目录下创建一个特殊的.gitignore文件&#xff0c;把要忽略的文件名填进去&#xff0c;Git就会自动忽略这些文件。 不需要从头写.gi…

mysql学习-常用sql语句

1、安装mysql参考网上链接&#xff0c;进入mysql数据库 mysql -u root -p 2、数据库操作 2.1、创建数据库 create database 数据库名 default character set utf8; 2.2、显示所有数据库 show databases; 2.3、选择数据库 use elementInfo; 2.4、删除数据库 drop database…

PostgreSQL16 的双向逻辑复制

一、配置 双向逻辑复制具体步骤 参考:PostgreSQL 16 双向逻辑复制与事务回环控制 - 墨天轮 1. 安装和准备环境 确保在所有参与复制的服务器上都安装了 PostgreSQL 16。主服务器&#xff1a;192.168.0.100从服务器&#xff1a;192.168.0.102 2. 配置 PostgreSQL 在每个服务…

FastAPI复杂查询终极指南:告别if-else的现代化过滤架构

title: FastAPI复杂查询终极指南:告别if-else的现代化过滤架构 date: 2025/3/14 updated: 2025/3/14 author: cmdragon excerpt: 本文系统讲解FastAPI中复杂查询条件的构建方法,涵盖参数验证、动态过滤、安全防护等18个核心技术点。通过引入策略模式、声明式编程等技术,彻…

C++前缀和

个人主页&#xff1a;[PingdiGuo_guo] 收录专栏&#xff1a;[C干货专栏] 大家好&#xff0c;今天我们来了解一下C的一个重要概念&#xff1a;前缀和 目录 1.什么是前缀和 2.前缀和的用法 1.前缀和的定义 2.预处理前缀和数组 3.查询区间和 4.数组中某个区间的和是否为特定…

机器学习基础

目录 泛化误差 偏差和方差 噪声 生成模型和判别模型 正态分布&#xff08;Normal Distribution&#xff09; 超参数选择 Grid Search 网格搜索 Random Search 随机搜索 Hyperopt Hyperas 参数估计方法对比 MLE 最大似然估计 MAP最大后验估计 贝叶斯估计 距…

中山六院团队发表可解释多模态融合模型Brim,可以在缺少分子数据时借助病理图像模拟生成伪基因组特征|顶刊解读·25-02-14

小罗碎碎念 在癌症诊疗领域&#xff0c;精准预测患者预后对临床决策意义重大。传统的癌症分期系统&#xff0c;如TNM分期&#xff0c;因无法充分考量肿瘤异质性&#xff0c;难以准确预测患者的临床结局。而基于人工智能的多模态融合模型虽有潜力&#xff0c;但在实际临床应用中…

系统可观测性(5)OpenTelemetry基础使用

系统可观测性(5)OpenTelemetry基础概念 Author: Once Day Date: 2025年3月12日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 本文档翻译整理自《OpenTelemetry Docs》&a…

OpenHarmony自定义子系统、部件与模块

如图所示&#xff0c;OpenHarmony系统源码中&#xff0c;大体上按照不同种类的功能分成多个子系统&#xff0c;然后一个子系统内部进一步在同类功能上的差异性划分成一个或多个部件&#xff0c;也就是说一个部件表示一个具体功能的源码集合。最后一个部件的源码再划分成一个或多…

【论文笔记】Contrastive Learning for Compact Single Image Dehazing(AECR-Net)

文章目录 问题创新网络主要贡献Autoencoder-like Dehazing NetworkAdaptive Mixup for Feature PreservingDynamic Feature Enhancement1. 可变形卷积的使用2. 扩展感受野3. 减少网格伪影4. 融合空间结构信息 Contrastive Regularization1. 核心思想2. 正样本对和负样本对的构建…

uni-app打包h5并部署到nginx,路由模式history

uni-app打包有些坑&#xff0c;当时运行的基础路径填写了./&#xff0c;导致在二级页面刷新之后&#xff0c;页面直接空白。就只能换一个路径了&#xff0c;nginx也要跟着改&#xff0c;下面是具体步骤。 manifest.json配置web 运行路径写/h5/&#xff0c;或者写你们网站的目…