golang闭包学习笔记

byte · · 490 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang闭包学习笔记

在开发中,经常会将一个方法的参数设置为可选,并设置一些默认值,使代码更通用简洁。在很多语言中这很容易,比如在C类语言中,可以使用相同方法名不同参数的多个版本(重写), 而在像python这样的语言中, 可以给参数一个默认值,并在调用方法时忽略它们。但是在 Go中, 这两种方式都用不了
  • 通过闭包的方式来解决这个问题

package main

import "fmt"

//用于初始化参数不定的情况,可以传入任意个参数
//可以给每个参数一个初始默认值,
//如果传入了ServerOption函数,就可以自定义这个字段的值,没传入这个字段的ServerOption则使用默认值

type options struct {
        a int
        b string
}

//定义了ServerOption为一个函数,参数是*options
type ServerOption func(*options)

func NewOption(opt ...ServerOption) *options {
        r := new(options)
        for _, o := range opt {
                o(r)
        }
        return r
}

func InitA(a int) ServerOption {
        return func(o *options) {
                o.a = a
        }
}

func InitB(b string) ServerOption {
        return func(o *options) {
                o.b = b
        }
}

func main() {
        initFuncs := []ServerOption{
                InitA(100),
                InitB("hello"),
        }
        //将需要初始化的字段对应的函数传入即可
        opts := NewOption(initFuncs...)
        fmt.Printf("opts = %+v\n", opts)
}
  • 对闭包的深入分析

在过去近十年时间里,面向对象编程大行其道,以至于在大学的教育里,老师也只会教给我们两种编程模型,面向过程和面向对象。孰不知,在面向对象思想产生之前,函数式编程已经有了数十年的历史。就让我们回顾这个古老又现代的编程模型,看看究竟是什么魔力将这个概念在21世纪的今天再次拉入我们的视野

闭包是函数式编程语言中的概念,没有研究过函数式语言的人可能很难理解闭包的强大

闭包=函数+引用环境
package main

import "fmt"

func main() {
        f := add()
        fmt.Printf("f(1) = %+v\n", f(1)) //1
        fmt.Printf("f(1) = %+v\n", f(1)) //1

        p := pp(0)
        fmt.Printf("p() = %+v\n", p()) //1
        fmt.Printf("p() = %+v\n", p()) //2
        fmt.Printf("p() = %+v\n", p()) //3
        fmt.Printf("p() = %+v\n", p()) //4
        fmt.Printf("p() = %+v\n", p()) //5

        lv := localVar()
        fmt.Printf("lv(0) = %+v\n", lv(0)) //0
        fmt.Printf("lv(1) = %+v\n", lv(1)) //1
        fmt.Printf("lv(2) = %+v\n", lv(2)) //3
        fmt.Printf("lv(3) = %+v\n", lv(3)) //6
        fmt.Printf("lv(4) = %+v\n", lv(4)) //10
}

func add() func(i int) int {
        num := 0
        return func(i int) int {
                return num + i
        }
}

//每次调用后,局部变量i的值会被保存
func pp(i int) func() int {
        return func() int {
                i++
                return i
        }
}

//每次调用后,局部变量sum会被保存
func localVar() func(int) int {
        sum := 0
        return func(x int) int {
                sum += x
                return sum
        }
}

闭包是匿名函数与匿名函数所引用环境的组合
匿名函数和它引用的变量以及环境,类似常规函数引用全局变量处于一个包的环境。

sum := 0
return func(x int) int {
    sum += x
    return sum
}

sum类比于全局变量,因此每次被赋值后,都会改变。
闭包被返回赋予一个同类型的变量时,同时赋值的是整个闭包的状态,该状态会一直存在外部被赋值的变量lv中,直到lv被销毁,整个闭包也被销毁。

  • 参考资料:

https://blog.csdn.net/qq_3597...
https://www.cnblogs.com/landv...
https://blog.keyboardman.me/2...
https://www.jianshu.com/p/034...


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:byte

查看原文:golang闭包学习笔记

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

490 次点击  
加入收藏 微博
上一篇:go 常量
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传