[Work in Progress]Confusing Code Examples in Golang

切片

切片分片操作

请问下面go程序的输出结果是什么?

package main

import (
        "fmt"
)

func main() {
        orderLen := 5
        order := make([]uint16, 2*orderLen)

        pollorder := order[:orderLen:orderLen]
        lockorder := order[orderLen:][:orderLen:orderLen]

        fmt.Println("len(pollorder) = ", len(pollorder))
        fmt.Println("cap(pollorder) = ", cap(pollorder))
        fmt.Println("len(lockorder) = ", len(lockorder))
        fmt.Println("cap(lockorder) = ", cap(lockorder))
}

运行结果

len(pollorder) =  5
cap(pollorder) =  5
len(lockorder) =  5
cap(lockorder) =  5

解释:程序中定义一个长度为10的切片order,pollorder和lockorder分别是对order切片做了order[low:high:max]操作生成的切片,最后程序分别打印pollorder和lockorder的容量和长度。order[low:high:max]操作意思是对order进行切片,新切片范围是[low, high),新切片容量是max。order长度为2倍的orderLen,pollorder切片指的是order的前半部分切片,lockorder指的是order的后半部分切片,即原order分成了两段。所以,pollorder和lockerorder的长度和容量都是orderLen,即5。

延迟调用

协程和延迟调用的估值时刻[1]

一个协程调用或者延迟调用的实参是在此调用发生时被估值的。更具体的说:

​ 对于一个延迟函数调用,它的实参是在此调用被推入延迟调用栈的时候被估值的

​ 对于一个协程调用,它的实参是在此协程被创建的时候估值的

一个匿名函数体内的表达式是在此函数被执行的时候才会被逐个估值的,不管此函数是被普通调用还是延迟/协程调用。

package main

import "fmt"

func main() {
	func() {
		for i := 0; i < 3; i++ {
			defer fmt.Println("a:", i)
		}
	}()
	fmt.Println()
	func() {
		for i := 0; i < 3; i++ {
			defer func() {
                // 调用时会发生栈逃逸
				fmt.Println("b:", i)
			}()
		}
	}()
}

运行结果:

a: 2
a: 1
a: 0

b: 3
b: 3
b: 3

解释,这两种defer调用的区别在于第一个i的值是通过传参获取的,第二个i的值是通过闭包进行传递的。第二个函数退出的时候开始执行defer调用,此时i的值是3,自然三次defer调用输出的值都是3。

参考资料:

[1].协程、延迟函数调用以及恐慌和恢复.https://gfw.go101.org/article/control-flows-more.html

[2].go专家编程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值