百木园-与人分享,
就是让自己快乐。

Go xmas2020 学习笔记 08、Functions, Parameters & Defer

课程地址 go-class-slides/xmas-2020 at trunk · matt4biz/go-class-slides (github.com)

主讲老师 Matt Holiday

image-20220401081031592

08-Functions, Parameters

functions

first class

image-20220405052151396

image-20220405052410972

你可以在函数体内声明函数,但必须是匿名函数,作为一个变量

function signatures

image-20220405052615027

函数签名指的是 函数参数类型与排列顺序、函数返回值

parameter

image-20220405052951913

image-20220405053010574

pass by value

func do(b [3]int) int {
	b[0] = 0
	return b[1]
}

func main() {
	a := [3]int{1, 2, 3}
	v := do(a) // ^ 数组被复制到函数的局部变量
	fmt.Println(a, v)
}
[1 2 3] 2

pass by reference

func do(b []int) int {
	b[0] = 0
	fmt.Printf(\"b2 @ %p\\n\", b)
	b = append(b, 100)
	b = append(b, 100)
	fmt.Printf(\"b3 @ %p\\n\", b)
	return b[1]
}

func main() {
	a := []int{1, 2, 3}
	fmt.Printf(\"b1 @ %p\\n\", a)
	v := do(a) // ^ 切片被复制到函数的局部变量
	fmt.Println(a, v)
}
b1 @ 0xc00012c078
b2 @ 0xc00012c078
b3 @ 0xc00013e060
[0 2 3] 2

func do(m1 map[int]int) {
	m1[3] = 0              // ^ 两个描述符和相同的哈希表,且哈希表有三个键,因此修改m1,m被修改
	m1 = make(map[int]int) // ^ 分配了新映射,但m不会被改变
	m1[4] = 4
	fmt.Println(\"m1\", m1)
}

func main() {
	m := map[int]int{4: 1, 7: 2, 8: 3}
	do(m)
	fmt.Println(m)
}
m1 map[4:4]
map[3:0 4:1 7:2 8:3]

the ultimate truth

image-20220405054837612

go 里只有值传递,函数内的变量都是局部变量,它被分配、拷贝实际参数的值,假如传入的是切片描述符,它也是被复制到局部变量里的。描述符被复制,切片底层数据没有被复制。

returns

image-20220405055316730

Recursion

image-20220405055450508

递归运行比迭代慢因为要创建一系列堆栈帧。

08-Defer

image-20220405055759385

image-20220405055925498

defer gotcha #1

image-20220405060115943

image-20220405060316700

Defer is based on function scope

第二个例子中,只有退出函数才会执行 defer 将会打开很多文件导致程序崩溃。所以直接使用 f.close 关闭文件。

defer gotcha #2

image-20220405060649324

defer 执行时,以参数实际的值拷贝传递进延迟函数并压入 defer栈 中,而不是引用。

image-20220405060931635

当我离开函数时执行延迟堆栈,延迟的匿名函数修改返回值 a


来源:https://www.cnblogs.com/linxiaoxu/p/16101379.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Go xmas2020 学习笔记 08、Functions, Parameters & Defer

相关推荐

  • 暂无文章