go从0到1项目实战体系四:函数

1. 函数:

go 复制代码
①. 声明:
   func 函数名字 (参数列表) (返回值列表){}

②. 举例:
   func add() {}
   func add(a int , b int) int {}
   func add(a int , b int) (int, int) {}

③. 特点:
   a. 不支持重载,一个包不能有两个名字一样的函数.
   b. 函数也是一种类型,一个函数可以赋值给变量(这个变量是一个指针指向函数地址).
   c. 匿名函数
   d. 多返回值
   e. type定义新的类型:type addFunc func(int, int) int  => 表示函数也是一种类型

④. 函数参数传递方式:
   a. 值传递
   b. 引用传递
   c. 值传递、引用传递,传递给函数的都是变量的副本.值传递是值的拷贝,引用传递是地址(8个字节)的拷贝.
   d. 一般来说,地址拷贝更为高效.值拷贝取决于拷贝的对象大小,对象越大,则性能越低.
   e. map、slice、chan、指针、interface默认以引用的方式传递.

⑤. 命名返回值的名字:
   func calc(a, b int) (sum int, avg int) {
      sum = a + b
      avg = (a +b) / 2
      return
   }

⑥. _标识符,用来忽略返回值.
   a, _ = add()
   _, a = add()

⑦. 可变参数:
   func add(arg...int) int {}              // 0个或多个参数
   func add(a int, arg...int) int {}       // 1个或多个参数,a是固定参数(可以有多个固定参数)
   a. arg是一个slice(切片).
   b. 通过arg[index]依次访问所有参数.
   c. 通过len(arg)来判断传递参数的个数.

2 defer:

(1). 概念:

go 复制代码
①. 当函数返回时,执行defer语句.因此,可以用来做资源清理.
②. 多个defer语句,按先进后出的方式执行(最晚的先执行).
③. defer语句中的变量,在defer声明时就决定了.
④. 举例:
   var a int = 111
   defer fmt.Println(a)      // 第3执行,打印值为111.在defer定义时,是什么值就是什么值.跟后面没关系.
   defer fmt.Println("333")  // 第2执行,因为先进后出,先入栈后出.
   a = 222
   fmt.Println(a)            // 第1执行
   结果:
   222
   333
   111

(2). 用途:

go 复制代码
①. 关闭文件句柄:
   file := open(filename)
   defer file.Close()
   // 文件操作

②. 锁资源释放:
   mc.Lock()
   defer mc.Unlock()
   // 其他操作

③. 数据库连接释放:
   conn := openDatabase()
   defer conn.Close()
   // 其他操作

3. 内置函数:

复制代码
①. close:
   主要用来关闭channel.

②. len:
   用来求长度,如string、array、slice、map、channel.

③. new:
   用来分配内存(值类型),如int、struct.返回的是指针.
   a := new(int)         // 返回一个内存地址
   *a = 100

④. make:
   用来分配内存(引用类型),如chan、map、slice.

⑤. append:
   用来追加元素到数组、slice中.

⑥. panic和recover:
   用来做错误处理.
   defer func() {
      if err := recover(); err != nil {
         fmt.Println(err)
      }
   }()            // 匿名函数自调用

   func initConfig() (err error) {
      return errors.New("init config failed")
   }
   func main() {
      err := initConfig()
      if err != nil {
         panic(err)
      }
   }

3.1 new与make的区别:

go 复制代码
①. new图:
   a. new一个[]int的切片                 => 第一行
   b. new返回一个指向切片的指针(*[]int)  => 第二行
   c. 这个地址指向一个实际的切片         => 第三行

②. make返回不是一个指针,就是一个切片.

③. 举例:
   c := new([]int)
	fmt.Println(c)             // &[],返回指向切片的指针.
	d := make([]int, 3)
	fmt.Println(d)             // [0 0 0],返回一个切片
   // 如果没有这句会报错:panic: runtime error: index out of range.
   // 因为new的时候,指针指向一个空的slice,slice没有初始化.
   *c = make([]int, 5)
   (*c)[0] = 1                // 因为是指针,加*号
	d[0] = 2

4. 递归函数:

斐波那契数(前两个数相加等于后一个数):

go 复制代码
func fab(n int) int {
	if n <= 1 {
		return 1
	}
	return fab(n-1) + fab(n-2)
}
func main() {
	for i := 0; i < 10; i++ {
		n := fab(i)
		fmt.Println(n)
	}
}

5. 闭包:

一个函数和与其相关的引用环境组合而成的实体.

go 复制代码
func Adder() func(int) int {          // 返回一个函数func(int) int
   var x int
   return func(d int) int {           // 这里必须与定义的返回函数一致
      x += d
      return x
   } 
}
func main() {
   var f = Adder()
   fmt.Print(f(1), " - ")             // 1
   fmt.Print(f(20), " - ")            // 21
   fmt.Print(f(300))                  // 321
}
相关推荐
Yang-Never19 分钟前
Kotlin协程 -> Job.join() 完整流程图与核心源码分析
android·开发语言·kotlin·android studio
TomCode先生2 小时前
c#动态树形表达式详解
开发语言·c#
高-老师3 小时前
基于R语言的物种气候生态位动态量化与分布特征模拟
开发语言·r语言·物种气候
大翻哥哥3 小时前
Python 2025:量化金融与智能交易的新纪元
开发语言·python·金融
weixin_437830944 小时前
使用冰狐智能辅助实现图形列表自动点击:OCR与HID技术详解
开发语言·javascript·ocr
鹿鹿学长4 小时前
2025年全国大学生数学建模竞赛(C题) 建模解析|婴儿染色体数学建模|小鹿学长带队指引全代码文章与思路
c语言·开发语言·数学建模
zhousenshan4 小时前
Python爬虫常用框架
开发语言·爬虫·python
是誰萆微了承諾5 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
weixin_456904275 小时前
Spring Boot 用户管理系统
java·spring boot·后端
DKPT5 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习