文章目录
- 循环语句
- 函数
- 声明
- init函数
- 匿名函数
- 闭包
- defer
- 个人博客:CSDN博客
循环语句
-
传统方法
-
func main() { for i := 1; i < 10; i++ { fmt.Println("hello!") } }
-
for - range方法
-
func main() { str := "abcde" for idx, val := range str { fmt.Printf("%v %c\n", idx, val) } }
-
idx是下标,val是值
-
go没有while和do-while使用for来实现
-
for { if i > 10 { break } fmt.Println(i) i++ }
函数
声明
-
func 函数名(形参列表)返回值列表 {}
-
func add(a int, b int) int { return a + b }
-
分包写函数
-
package main import ( "fmt" "go_code/project01/model" ) func main() { fmt.Println(model.Add(1, 2)) }
-
包名和文件夹名可以不一致,这样下面调用的时候也要用另外的包名,一般来说,我们习惯于名字保持一致,这样我们导入包的时候,就就能知道包名是什么了。
-
再复习一个点,Go语言没有public private关键字,是用变量和函数第一个字母大小写来判断公有还是私有,大写是公有,小写是私有。
-
导包的路径,是从GOPATH/src 后面的部分,一直导到包文件夹。
-
在同一包下,不能又相同的函数名,不支持函数的重载
-
如果要编译可执行文件必须声明main包,main包是唯一的。
init函数
- 每个源文件都可以包含一个init函数,这个函数会在main函数之前被调用,全局变量定义,init函数,main函数的顺序调用
- 可能相当于类当中的构造函数
匿名函数
-
相当于把整个函数体当作函数的名字,后面的括号就是传入的参数列表
-
func main() { res := func(a int, b int) int { return a + b }(1, 2) fmt.Println(res) }
-
如果不带括号,可以重复调用匿名函数,类似lamda表达式
-
res := func(a int, b int) int { return a + b } //fmt.Println(res) fmt.Println(res(1, 2))
闭包
-
func main() { f := func() func(int) int { var n int = 10 return func(x int) int { n = x + n return n } } ff := f() ff(1) ff(2) fmt.Println(ff(3)) }
-
答案16
-
这里是一个返回值是(int)int的匿名函数,返回了一个含有未知参数并且引用了n的匿名函数,对这个匿名函数多次调用。
-
函数和引用的外部变量构成了闭包,相当于一个类,第一次调用得到一个匿名函数,可以类比成一个构造方法,构造出了一个类,n是类的一个成员。
-
或者,我们这样想,这个匿名函数和他所引用的变量构成的闭包,在匿名函数第一次返回的时候,这些变量也在相同的作用域进行声明。
defer
-
to delay sth until a later time 推迟;延缓;展期(摘自牛津)
-
func main() { defer fmt.Println("ok1") defer fmt.Println("ok2") fmt.Println("ok3") fmt.Println("ok4") }
-
输出顺序是:3->4->2->1
-
defer先不执行,等到函数快要释放的时候,defer执行顺序遵从栈的顺序,先进后出
-
当语句压入栈的时候,相关引用的变量也会拷贝一份进入栈。