本文大概总结了本人在 Golang
编程工作中遇到的疑难点, 最后更新于 20190516
延迟函数
延迟函数defer
就是在函数调用返回后添加的函数调用
坑1. 延迟函数参数实时解析
func main() {
a()
}
func a() {
i := 1
defer fmt.Println(i)
i++
}
程序执行的最终结果是 1
虽然我们在 defer
后面定义的是一个带变量的函数 fmt.Println(i)
但这个变量i
在defer
被声明的时候,就已经确定为确定的值了, 相当于fmt.Println(0)
坑2. 延迟函数在匿名返回值和命名返回值函数中的不同表现
func main() {
fmt.Println(a())
fmt.Println(b())
}
func a() int {
var i int
defer func() {
i++
}()
return i
}
func b() (i int) {
defer func() {
i++
}()
return i
}
程序执行的最终结果是 0 1
在a函数中,可以理解成Go自动创建了一个返回值retValue
,相当于执行retValue = i,然后检查是否有defer,如果有则执行,再返回刚才创建的返回值retValue
在b函数中,由于返回值在方法定义时已经被定义,所以没有创建retValue的过程,i就是retValue,defer对于result的修改也会被直接返回
坑3.程序退出时延迟函数不会被执行
func main() {
fmt.Println("1")
defer fmt.Println("0")
os.Exit(0)
}
程序执行的最终结果是1
参考链接:
字典
坑1. 字典的操作不是原子操作
参考链接:
interface与nil
坑1, 接口值的返回总是非nil的
底层的interface实现是有一个类型一个内部值,只有在内部值和类型都未设置时(nil, nil),一个接口的值才为 nil
func main() {
err := FindALL()
if err != nil {
fmt.Println(1)
}
if err.(*MyErr) != nil {
fmt.Println(2)
}
}
type MyErr struct {
}
func (m *MyErr) Error() string {
return ""
}
func FindALL() error {
var p *MyErr
return p
}
程序执行的最终结果是1
参考链接: