今头条!Golang 断言与闭包使用解析
目录
1. Go断言的使用2. 闭包的解读2.1 指针传递2.2 延迟绑定2.3 Go Routine的延迟绑定1. Go断言的使用
Go中的断言用于判断变量的类型,其使用形式如下所示:
value, ok := x.(T)
上面的代码是判断x是否为T类型的变量:
(资料图)
如果 T 的某个具体的类型,断言会检查 x 是否为该类型,如果是的话买就返回 x 以及一个布尔值true
,反之返回一个false
如果 T 是接口类型,类型断言会检查 x 的动态类型是否满足 T。如果检查成功,返回值是一个类型为 T 的接口值,以及一个布尔值true
,反之返回一个false
我们也可以不接受返回的布尔值,在这种情况下,如果断言失败,会直接panic
,所以非常不推荐这种处理方式
另外,断言和可以与switch配合使用
switch a.(type) { case int: fmt.Println("the type of a is int") case string: fmt.Println("the type of a is string") case float64: fmt.Println("the type of a is float") default: fmt.Println("unknown type") }
2. 闭包的解读
闭包是由函数和与其相关的引用环境组合而成的实体。
概念上说起来有些抽象,下面我们以一个具体的例子来理解。
func foo1(x int) func() { return func() { x = x + 1 fmt.Printf("foo2 val = %d\n", x) } } f1 := foo1(1) f1() // 2 f1() // 3
在上面的例子中,f1() 与他的变量x(值为1)共同组成了一个闭包,每次调用f1(),x的值就会+1并且打印。
从某种意义上来说,闭包延长了变量的生命周期(栈上分配改为了堆上分配)。
2.1 指针传递
func foo2(x *int) func() { return func() { *x = *x + 1 fmt.Printf("foo2 val = %d\n", *x) } } x := 1 f1 := foo2(&x) f2 := foo2(&x) f1() // 2 f2() // 3
通过第一个例子,我们知道,函数以及其环境(传入的变量)组成了闭包,这个时候,如果传入的是一个指针,那么就会存在多个闭包共用一个变量的情况。
2.2 延迟绑定
闭包的延迟绑定,通俗地说,就是闭包的函数在第一次调用的时候才会与环境的变量进行绑定,我们依然以上面提到的两个函数为例子:
func foo1(x int) func() { return func() { x = x + 1 fmt.Printf("foo2 val = %d\n", x) } } func foo2(x *int) func() { return func() { *x = *x + 1 fmt.Printf("foo2 val = %d\n", *x) } } x := 1 f1 := foo1(x) f2 := foo2(&x) f2() // 2 f1() // 3我们创建了f1与f2两个闭包函数,以及变量 x 的值为1在f1与f2创建的时候,变量并没有与函数绑定第一次调用f2()时,&x与其绑定,x的值+1,变为2第一次调用f1()时,x与其绑定,这时x已经变为2了,再+1,所以变为3
2.3 Go Routine的延迟绑定
我们在一个函数中启动 Go Routine 调用另一个函数:
func show(v interface{}) { fmt.Printf("foo4 val = %v\n", v) } func foo4() { values := []int{1, 2, 3, 5} for _, val := range values { go show(val) } } foo4() //foo3 val = 2 //foo3 val = 3 //foo3 val = 1 //foo3 val = 5
因为Go Routine的执行顺序是随机并行的,因此执行多次foo4()
输出的顺序不一行相同,但是一定打印了“1,2,3,5”各个元素。
但是,如果我们以匿名函数的形式尝试复现上面的逻辑,会发现:
func foo5() { values := []int{1, 2, 3, 5} for _, val := range values { go func() { fmt.Printf("foo5 val = %v\n", val) }() } } foo5() //foo3 val = 5 //foo3 val = 5 //foo3 val = 5 //foo3 val = 5
其实这个问题的本质同闭包的延迟绑定,或者说,这段匿名函数的对象就是闭包。在我们调用go func() { xxx }()
的时候,只要没有真正开始执行这段代码,那它还只是一段函数声明。而在这段匿名函数被执行的时候,才是内部变量寻找真正赋值的时候。for-loop的遍历几乎是“瞬时”完成的,4个Go Routine真正被执行在其后,所以会产生上面的情况。
到此这篇关于Golang 断言与闭包使用解析的文章就介绍到这了,更多相关Go 断言与闭包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 1转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 2充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 3好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 4名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 5亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战
- 6京东绿色建材线上平台上线 新增用户70%来自下沉市场
- 7网红淘品牌“七格格”chuu在北京又开一家店 潮人新宠chuu能红多久
- 8市场竞争加剧,有车企因经营不善出现破产、退网、退市
- 9北京市市场监管局为企业纾困减负保护经济韧性
- 10市场监管总局发布限制商品过度包装标准和第1号修改单