当前位置: 首页 > news >正文

【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) bool

func 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 string
    port int
    timeout time.Duration
    maxConn 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 := initialValue
    for _, 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 string
    Age  int
}

type SortBy func(p1, p2 *Person) bool

type PersonSorter struct {
    people []Person
    less   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 := false
    var result interface{}
    
    return func() interface{} {
        if !computed {
            fmt.Println("执行昂贵计算...")
            // 模拟耗时操作
            time.Sleep(1 * time.Second)
            result = 42
            computed = true
        }
        return result
    }
}

// 使用示例
func main() {
    // 创建惰性计算
    lazy := computeExpensiveValue()
    
    fmt.Println("惰性计算创建后,尚未执行计算")
    
    // 调用时才执行实际计算
    value := lazy()
    fmt.Println("第一次获取值:", value)
    
    // 再次调用不会重复计算
    value = lazy()
    fmt.Println("第二次获取值:", value)
}

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

相关文章:

  • 【数控系统】第二章 LinuxCNC源码介绍
  • TCP/IP 协议精讲-精华总结版本
  • 【SpringMVC】入门版
  • 网络运维学习笔记(DeepSeek优化版) 016 HCIA-Datacom综合实验01
  • Apache Shiro反序列化漏洞深度剖析:从原理到利用
  • PostgreSQL的学习心得和知识总结(一百七十一)|深入理解PostgreSQL数据库之 外连接消除 的使用和实现
  • pytest自动化测试[面试篇]
  • linux sentos7 遗忘root用户密码
  • VMware虚拟机安装Windows10系统配置docker容器
  • MacOS 15.3.1 安装 GPG 提示Error: unknown or unsupported macOS version: :dunno
  • 单片机—中断系统
  • Linux之进程控制
  • HTML5-基础知识
  • CentOS 6 YUM源切换成国内yum源
  • 适合企业内训的AI工具实操培训教程(37页PPT)(文末有下载方式)
  • 优艾智合加码具身智能赛道,“一脑多态”技术矩阵率先规模化落地
  • vue3 中使用 Recorder 实现录音并上传,并用Go语言调取讯飞识别录音(Go语言)
  • HAL库STM32常用外设—— CAN通信(一)
  • JVisualVM 监控线程池状态
  • Word 小黑第27套
  • 经济日报整版聚焦:上海构建法治化营商环境,交出高分答卷
  • 白天气温超30℃的北京,晚间下起了冰雹
  • 外交部:正确认识和对待历史是检验日本能否恪守和平发展承诺的重要标准
  • 《新时代的中国国家安全》白皮书(全文)
  • 人民日报刊文:加快解放和发展新质战斗力
  • 洗冤录|县令遇豪强:黄榦处理的一起地产纠纷案