函数

package main

import "fmt"

// 函数:一段代码的封装

func f1(){
fmt.Println("Hello 中国!")
} func f2(name string) {
fmt.Println("Hello", name)
} // 带参数和返回值的函数
func f3(x int, y int) int {
sum := x + y
return sum
} // 参数类型简写
func f4(x, y int) int {
return x + y
} // 可变参数
func f5(title string, y ...int) int {
fmt.Println(y) // y是一个int类型的切片
return 1
} // 命名返回值
func f6(x, y int) (sum int) {
sum = x + y // 如果使用命名的返回值,那么在函数中可以直接使用返回值变量
return // 如果使用命名的返回值 return 后面可以省略返回值变量
} // Go语言中支持多个返回值
func f7(x, y int) (sum, sub int) {
sum = x + y
sub = x - y
return
} func main () {
f1()
f2("理想")
f2("梦想")
f3(100, 200) // 调用函数
fmt.Println(f3(100, 200))
ret := f3(300, 400)
fmt.Println(ret) f5("太阳", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 在一个命名的函数中不能够再声明命名函数
// func f8() { // } }

defer语句

defer语句会将其后面跟随的语句进行延迟处理

在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行

先被defer的语句最后被执行,最后被defer的语句,最先被执行

package main

import "fmt"

// defer

// defer多用于函数结束之前释放资源(文件句柄、数据库连接、socket连接)
func deferDemo(){
fmt.Println("start")
defer fmt.Println("hello") // defer把它后面的语句延迟到函数即将返回的时候再执行
defer fmt.Println("apple") // 一个函数中可以有多个defer语句
defer fmt.Println("banana") // 多个defer语句安装先进后出(后进先出)的顺序延迟执行
fmt.Println("end")
} func main(){
deferDemo()
}

defer执行时机

return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步

defer语句执行的时机在返回值赋值操作后,RET指令执行前

package main

import "fmt"

// Go语言中函数的return不是原子操作,在底层分为两步来执行
// 第一步:返回值赋值
// defer
// 第二版:真正的RET返回
// 函数中如果存在defer,那么defer执行的时机是在第一步和第二步之间 func f1() int {
x := 5
defer func() {
x++ // 修改的是x不是返回值
}()
return x
} func f2() (x int) {
defer func() {
x++
}()
return 5 // 返回值=x
} func f3() (y int) {
x := 5
defer func() {
x++ // 修改的是x
}()
return x // 返回值=y=x=5
}
func f4() (x int) {
defer func(x int) {
x++ // 改变的是函数中的副本
}(x)
return 5 // 返回值=x=5
}
func main() {
fmt.Println(f1())
fmt.Println(f2())
fmt.Println(f3())
fmt.Println(f4())
}

最新文章

  1. 标准BST二叉搜索树写法
  2. Azure CDN Smart Routing 功能正式上线
  3. a c lang in linux
  4. SpringMVC综合使用手机管理系统Controller层开发
  5. 为什么数据可以从pl/sql查出来而使用ado.net查询,结果却是空?
  6. java高精度进制转换
  7. winzip15.0许可证
  8. 在ubuntu上安装k-vim
  9. VB6之CRC32
  10. selenium WebDriver 八种定位方式源码
  11. linux_nginx环境配置
  12. C#/VB.NET 给Word文档添加/撤销书签
  13. [爬虫进阶]使用Jsoup取代你的一切网络请求方法(java,post,get,代理IP)
  14. vue及Eelement使用过程中遇到的一些问题
  15. Django 模板继承
  16. Layout Inflation :Unconditional layout, inflation from view adapter
  17. Flutter基础用法解析
  18. 爬虫利器_you-get
  19. 统计Mongo数组中相同对象的属性之和
  20. 网络编程学习笔记一:Socket编程

热门文章

  1. 解释 JDBC 抽象和 DAO 模块?
  2. 学习 MongoDB(一)
  3. idea中Git的配置和Github上推拉项目
  4. Rust 中的数据布局--非正常大小的类型
  5. POJ 2236:Wireless Network
  6. ES6-11学习笔记--异步迭代
  7. sring框架的jdbc应用
  8. localStorage存储返回过来的对象 显示object object的问题
  9. 『现学现忘』Git基础 — 3、Git介绍
  10. HTTP和HTTPS有什么不同