diff --git a/day03/README.md b/day03/README.md index 9171c68..40a9ef3 100644 --- a/day03/README.md +++ b/day03/README.md @@ -5,7 +5,7 @@ ## 课程内容 + [Go语言函数](./function/README.md) -+ defer与异常 ++ [defer与异常](./error/README.md) + Go语言结构体 + Go语言指针 + 扩展反射与内存对齐 \ No newline at end of file diff --git a/day03/error/README.md b/day03/error/README.md new file mode 100644 index 0000000..73308d4 --- /dev/null +++ b/day03/error/README.md @@ -0,0 +1 @@ +# 异常处理 \ No newline at end of file diff --git a/day03/error/main.go b/day03/error/main.go new file mode 100644 index 0000000..7905807 --- /dev/null +++ b/day03/error/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + +} diff --git a/day03/function/README.md b/day03/function/README.md index e2dcbf2..cdee10a 100644 --- a/day03/function/README.md +++ b/day03/function/README.md @@ -1,2 +1,3 @@ # 函数 +[函数](https://gitee.com/infraboard/go-course/blob/master/zh-cn/base/func.md#%E7%A4%BA%E4%BE%8B%E5%B8%B8%E8%A7%81%E5%87%BD%E6%95%B0%E6%A8%A1%E5%BC%8F) \ No newline at end of file diff --git a/day03/function/main.go b/day03/function/main.go index ce16bc2..c2cc321 100644 --- a/day03/function/main.go +++ b/day03/function/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" ) func main() { @@ -23,6 +24,34 @@ func main() { arg2 := []int{2, 3, 4} appendAndChangeV2(&arg2) fmt.Println(arg2) + + // 1. 普通函数名作为参数传递, logfn, 把处理抽象成函数,往往是为了复用这段代码 + // 2. 匿名函数, 临时使用一次,不需要复用 + // logfn := func(log string) { + // fmt.Println(log) + // } + // 3. 临时使用,直接定义匿名函数,不需要赋值给变量 + + // logfn func(string), Go里面非常常见的写法(90%) + TaskHandler(&RunTaskRequest{Name: "task1"}, func(s string) { + fmt.Println(s) + }) + + counterFn := counter() + fmt.Println(counterFn(), counterFn(), counterFn()) + + // fib + fmt.Println(fib(5)) + fmt.Println(fib(9)) + + // 变量目录, 打印了文件名称 + walkDir(".", func(filePath string) { + fmt.Println(filePath) + }) +} + +func logfn(log string) { + fmt.Println(log) } // (x int, y int) @@ -89,7 +118,7 @@ func appendAndChangeV2(s *[]int) { (*s)[0] = 8 // 这一行只影响内部副本(若已扩容(B))) } -type Task struct { +type RunTaskRequest struct { Name string Params map[string]string } @@ -100,10 +129,80 @@ type Task struct { // 通过回调的方式快速 返回给调用方 // 回调函数: 函数作为参数传递 // TaskHandler func(*Task) []string -func TaskHandler(t *Task, logfn func(string)) { +func TaskHandler(req *RunTaskRequest, logfn func(string)) { // return []string{"log1", "log2"} + // 执行任务过程中的日志 通过 logfn 回调函数返回给调用方 logfn("任务开始") logfn("任务进行中...") logfn("任务结束") } + +func counter() func() int { + // 依赖的变量 + i := 0 + + // m 会被GC回收掉, 外部没有引用记录,意思就是被用完了 + m := 10 + fmt.Println(i, m) + + // i 还被返回的依赖者, 除非这个函数不用了 i才会被回收 + return func() int { + i++ + return i + } +} + +// 斐波那契数列 fn(n) = fn(n-1) + fn(n-2) +// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... +// fib(5) = fib(4) + fib(3) +// fig(2) = 1: n=2 fib(1) + fib(0) +// fib(0) = 0 +// fib(1) = 1 +// fib(2) = fib(1) + fib(0) = 1 +// fib(3) = fib(2) + fib(1) = 1 + 1 = 2 +// fib(4) = fib(3) + fib(2) = 2 + 1 = 3 +// fib(5) = fib(4) + fib(3) = 3 + 2 = 5 +// 函数作为参数传递, 递归调用,知道退出 +// 1: 1 +// 2: 1 +// 3: 2 +// 4: 3 +// 5: 5 +// 6: 8 +// 7: 13 +// 8: 21 +// 9: 34 +// fib(5) = fib(4) + fib(3) +// fib(4) = fib(2) + fib(1) + fib(2) +// fib(3) = fib(2) + fib(1) +// fib(5) = fib(2) + fib(1) + fib(2) + fib(2) + fib(1) = 1 + 1 + 1 + 1 + 1 = 5 +func fib(n int) int { + fmt.Println("fib:", n) + switch { + // 第一个 + case n <= 0: + return 0 + // 第2个 + case n <= 2: + return 1 + default: + // 有了2个 + return fib(n-1) + fib(n-2) + } +} + +// 最常见的就是 遍历目录里面的文件 +func walkDir(path string, fn func(string)) { + files, _ := os.ReadDir(path) + // 读取path目录下的文件和子目录 + for _, file := range files { + // 如果是目录, 继续往下找 + if file.IsDir() { + walkDir(path+"/"+file.Name(), fn) + } else { + // 文件, 调用fn函数处理 + fn(path + "/" + file.Name()) + } + } +}