Browsed by
分类:Go

Gin、GORM 中责任链模式的使用

Gin、GORM 中责任链模式的使用

责任链模式在 GoF 的《设计模式》一书中是这样定义的

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

解耦请求的发送和接收,让多个接收对象都有机会处理这个请求。请求在多个串联的对象中传递,直到有对象能处理它。看下面这个例子

package main

import "fmt"

type HandlerFunc func(*Request) bool

type Request struct {
    url      string
    handlers []HandlerFunc
}

func (r *Request) Use(handlerFunc HandlerFunc) {
    r.handlers = append(r.handlers, handlerFunc)
}

func (r *Request) Run() {
    for _, handler := range r.handlers {
        if handler(r) {
            break
        }
    }
}

// 测试
// 输出 2 
func main() {
    r := &Request{}
    r.Use(func(r *Request) bool {
        return false
    })
    r.Use(func(r *Request) bool {
        fmt.Print(2, " ")
        return true
    })
    r.Use(func(r *Request) bool {
        fmt.Print(3, " ")
        return true
    })
    r.Run()
}

例子中定义了一个请求 Request,请求可以被多个 HandlerFunc 处理,如果某个 HandlerFunc 处理成功则结束处理,其中 HandlerFunc 可以通过 Request.Use() 方法进行添加。

阅读全文

Go 函数式编程

Go 函数式编程

函数式编程的一个重要特性是「函数是第一等公民」,本文以 Go 为例解释这个概念,之后介绍高阶函数、匿名函数、闭包等概念,最后介绍一些标准库和项目中的实践例子。

函数是第一等公民

先看一个普通变量赋值的例子

v := 100
fmt.Printf("value %v type %T\n", v, v)

输出

value 100 type int

如果我们将变量改为函数呢,比如

fn := func(x int) int { return x * x }
fmt.Printf("value %v type %T\n", fn, fn)

输出

value 0x10a8da0 type func(int) int

这里说明函数也可以赋值给变量。

所谓「函数是第一等公民」,也就是函数与其他数据类型一样,处于平等地位,可以

  • 赋值给同类型变量
  • 作为入参传递给函数
  • 作为函数的返回结果

阅读全文