golang利用函数闭包实现简单的中间件

 更新时间:2023年10月08日 08:37:10   作者:言志志  
中间件设计模式是一种常见的软件设计模式,它在许多编程语言和框架中被广泛应用,这篇文章主要为大家介绍一下golang利用函数闭包实现一个简单的中间件,感兴趣的可以了解下

什么叫做中间件

中间件设计模式是一种常见的软件设计模式,它在许多编程语言和框架中被广泛应用,包括Go、Node.js、Python等。

中间件模式的核心思想是将一系列的处理逻辑组合在一起,形成一个处理链(或称为管道),每个处理逻辑被封装成一个中间件函数。每个中间件函数可以在请求处理的不同阶段添加额外的功能或逻辑,而无需修改原始的处理函数。

中间件模式的优势在于它提供了一种可插拔、可组合的方式来扩展和定制请求处理过程。以下是中间件模式的一些关键特点:

  • 可插拔性(Pluggability):中间件模式允许将中间件函数插入到处理链中,以添加新的功能或逻辑。这种可插拔性使得我们可以根据需要动态地添加、移除或替换中间件,而无需修改原始的处理函数。
  • 复用性(Reusability):中间件模式可以将通用的功能或逻辑封装成可复用的中间件函数。这些中间件函数可以在不同的请求处理中重复使用,提高了代码的复用性。
  • 可组合性(Composability):中间件模式允许将多个中间件函数按照特定的顺序组合在一起,形成一个处理链。每个中间件函数可以在调用原始处理函数之前、之后或两者之间执行自己的逻辑。这种可组合性使得我们可以构建复杂的处理逻辑,将各个中间件函数按需组合,形成一个完整的请求处理流程。
  • 责任链(Chain of Responsibility):中间件模式的处理链形成了一个责任链结构,每个中间件函数都有机会处理请求或将处理传递给下一个中间件。这种责任链结构可以根据实际需求动态调整中间件的顺序,实现不同的处理流程。

中间件模式在Web开发中得到了广泛应用,特别是在处理HTTP请求的过程中。常见的中间件功能包括身份验证、日志记录、请求解析、缓存、错误处理、压缩等。通过将这些功能封装成中间件函数,并按照需要组合起来,我们可以轻松地构建灵活、可扩展的Web应用程序。

利用函数闭包实现一个简单的中间件

下面我以求两数之和为例,实现一个简单的中间件,可以看如下代码

package main
import "log"
func sum(a, b int) int {
   return a + b
}
func Zh(f func(a, b int) int) func(a, b int) int {
   return func(a, b int) int {
      log.Printf("日志中间件,记录操作数: a: %d b: %d\n", a, b)
      return f(a, b)
   }
}
func main(){
   addWithLogging := Zh(sum)
   result := addWithLogging(2, 3)
   result2 := addWithLogging(5, 6)
   fmt.Println(result,result2)
}

上面的代码,可以被认为是一个中间件函数的实现,我们在sum函数执行之前,先进行了日志的记录,并且又不影响原函数的执行,就像添加了一个过程一样,这个中间件函数可以被插入到处理链中,在执行原始函数之前记录操作数的日志,其实你可以发现,我不过就是相当于将传入的函数进行封装了一下

当然,我们还可以更加优雅,那就是抽象为一个函数类型,并且我们可以发现,Zh中间件处理后的返回值,还可以继续被它处理。

// 优雅地处理
type F func(func(a, b int) int

对了,上面的函数是利用闭包实现的,首先闭包是指函数内部定义的函数可以访问其外部函数的变量。

而在这个例子中,匿名函数func(a, b int) int是在Zh函数内部定义的,并且可以访问外部函数的参数f

具体来说,Zh函数接受一个函数类型的参数f,并返回一个具有相同函数签名的函数。在返回的函数内部,它使用了log.Printf打印日志,并调用了外部函数的参数f

由于返回的函数是在Zh函数内部定义的,它可以访问Zh函数的参数f,即使Zh函数已经执行完毕并返回了。这是因为闭包函数捕获了其外部函数的变量,形成了一个闭包环境,使得返回的函数仍然可以访问外部函数的变量。

当然,我只是想通过这个简单的样例让你知道,什么是中间件

像go中的gin框架中的中间件的使用就很成熟,gin巧妙的把具体实现过程进行了隐藏,让你只要写好一个函数,然后插入使用即可,非常优雅,而本文的样例,其实是把隐藏的过程进行了展示,详情请看gin的源码。

到此这篇关于golang利用函数闭包实现简单的中间件的文章就介绍到这了,更多相关go中间件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入解析Go template模板使用详解

    深入解析Go template模板使用详解

    这篇文章主要介绍了深入解析Go template模板使用详解,需要的朋友可以参考下
    2022-04-04
  • golang读取yaml文件的示例代码

    golang读取yaml文件的示例代码

    本文主要介绍了golang读取yaml文件的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-09-09
  • Go语言应该什么情况使用指针

    Go语言应该什么情况使用指针

    go语言的指针类型和C/C++的指针类型用法是一样的,那么Go语言应该什么情况使用指针,本文就详细的介绍一下,感兴趣的可以了解一下
    2021-07-07
  • Go语言中的通道channel详情

    Go语言中的通道channel详情

    这篇文章主要介绍了Go语言中的通道channel,在Go语言中管道类似于一个数据流,每次放入或者取出一部分数据,数据取出后原通道内的数据就删除掉,在linux操作系统中管道会将函数的返回结果作为下一个函数的参数,下文详细内容需要的朋友可以参考下
    2022-02-02
  • 关于golang类型推断和变量重声明详解

    关于golang类型推断和变量重声明详解

    在Go语言中,类型推断可以根据变量的初始化值自动推断出变量的类型,而不需要显式地声明变量类型,变量重声明可以在同一作用域内重复声明一个变量,只要其中至少一个是新的变量,本就简单的给大家介绍一下golang类型推断和变量重声明,需要的朋友可以参考下
    2023-08-08
  • 如何在Golang中运行JavaScript

    如何在Golang中运行JavaScript

    最近写一个程序,接口返回的数据是js格式的,需要通过golang来解析js,所以下面这篇文章主要给大家介绍了关于如何在Golang中运行JavaScript的相关资料,需要的朋友可以参考下
    2022-01-01
  • 简单聊聊Go语言里面的闭包

    简单聊聊Go语言里面的闭包

    这篇文章主要为大家详细介绍了Go语言中闭包的原理与实现的相关资料,文中的示例代码讲解详细,对我们学习Go语言有一定帮助,需要的可以参考一下
    2022-11-11
  • Go语言中匿名嵌套和类型嵌套的区别解析

    Go语言中匿名嵌套和类型嵌套的区别解析

    在Go语言中,匿名嵌套结构体和与类型同名的嵌套结构体不是完全等价的,它们有一些重要的区别,这篇文章主要介绍了Go语言中匿名嵌套和类型嵌套的区别,需要的朋友可以参考下
    2023-09-09
  • 如何在Go语言中高效使用Redis的Pipeline

    如何在Go语言中高效使用Redis的Pipeline

    在 Redis 中,Pipeline 就像一条流水线,它允许我们将多个命令一次性发送到服务器,下面我们就来看看如何在Go语言中高效使用Redis的Pipeline吧
    2024-11-11
  • go实现Redis读写分离示例详解

    go实现Redis读写分离示例详解

    本篇文章将介绍Redis通信协议RESP, 而后在使用go来编写一个中间件,从而来完成Redis读写分离,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论