# Go学习-Day3

文章目录

    • 循环语句
    • 函数
      • 声明
      • 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执行顺序遵从栈的顺序,先进后出

  • 当语句压入栈的时候,相关引用的变量也会拷贝一份进入栈。

你可能感兴趣的:(Go,golang,学习,开发语言)