Go学习笔记
目录
Go语言基础
函数
函数是组织好的、可重复使用的、用于执行指定任务的代码块。- Go语言中支持
函数、匿名函数和闭包, 并且函数在Go语言中属于 “一等公民” 。
函数定义
- Go语言中定义函数使用
func关键字.
| |
- 名词解析:
- 函数名: 由字母、数字、下划线组成。但函数名的第一个字母不能是数字。在同一个包内, 函数名也称不能重名。
- 参数: 参数由
参数变量和参数变量类型组成, 多个参数之间使用,分隔。 - 返回值: 返回值由
返回值变量和其变量类型组成, 也可以只写返回值的类型, 多个返回值必须用()包裹, 并用,分隔。 - 函数体: 实现指定功能的代码块。
| |
- 输出:
| |
函数参数
- 函数参数由
参数变量和参数变量类型组成, 如果相邻变量的类型相同, 则可以省略类型。 - 函数参数类型相同时可以简写, 如:
func sum(x, y int) - Go语言是没有 默认参数的
| |
- 输出:
| |
| |
- 输出:
| |
函数可变参数
可变参数是指函数的参数数量不固定, Go语言中的可变参数通过在参数名后加...来标识。可变参数要放在参数最后面, 如:func a(x int, y...int)
| |
- 输出:
| |
函数返回值
- Go语言中通过
return关键字向外输出返回值。 - Go语言中函数支持多返回值, 函数如果有多个返回值时必须用
()将所有返回值包裹起来。 - 函数定义时可以给返回值命名, 并在函数体中直接使用这些变量, 最后通过
return关键字返回。 - 多返回值也支持类型简写
| |
- 输出:
| |
defer语句
Go语言中的
defer语句会将其后面跟随的语句进行延迟处理。在defer归属的函数即将返回时, 将延迟处理的语句按defer定义的逆序进行执行, 也就是说, 先被defer的语句最后被执行, 最后被defer的语句,最先被执行。由于
defer语句延迟调用的特性,所以defer语句能非常方便的处理资源释放问题。比如: 资源清理、文件关闭、解锁及记录时间等。在Go语言的函数中
return语句在底层并不是原子操作, 它分为给返回值赋值和RET指令两步。而defer语句执行的时机就在返回值赋值操作后, RET指令执行前。
| |
| |
- 输出:
| |
defer 题目分析
| |
- 输出:
| |
函数 变量作用域
- 函数
全局变量与局部变量同时存在时, 优先使用 函数内定义的局部变量, 然后在使用全局变量。
| |
- 输出:
| |
函数类型与变量
- 函数类型变量
| |
- 输出:
| |
高阶函数
高阶函数分为
函数作为参数和函数作为返回值两部分。函数作为参数
| |
- 输出:
| |
- 函数作为返回值
| |
- 输出
| |
匿名函数和闭包
- 匿名函数 - 匿名函数就是没有函数名的函数。
- 匿名函数多用于实现回调函数和闭包。
| |
| |
- 输出:
| |
闭包
- 闭包指的是一个函数和与其相关的引用环境组合而成的实体。简单来说:
闭包=函数+引用环境(外层变量的引用)。
| |
- 输出:
| |
| |
- 输出:
| |
- 闭包的应用一
| |
- 输出:
| |
- 闭包的应用二
| |
- 输出:
| |
内置函数
| 内置函数 | 说明 |
|---|---|
| close | 主要用来关闭channel |
| len | 用来求长度,比如string、array、slice、map、channel |
| new | 用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针 |
| make | 用来分配内存,主要用来分配引用类型,比如chan、map、slice |
| append | 用来追加元素到数组、slice中 |
| panic和recover | 用来做错误处理 |
panic/recover
- Go语言中 版本小于等于
1.12是没有异常机制, 但是使用panic/recover模式来处理错误。panic可以在任何地方引发。 recover()必须搭配defer使用。defer一定要在可能引发panic的语句之前定义。
- Go语言中 版本小于等于
引发 panic
| |
- 输出:
| |
- 使用 recover 恢复错误
| |
- 输出:
| |
函数练习题
| |
| |
- 输出:
| |
指针
- Go语言中的指针区别于C/C++中的指针, 不能进行偏移和运算, 是安全指针。
- Go语言中的指针需要先知道3个概念: 指针地址、指针类型和指针取值。
- Go语言中的函数传参都是值拷贝, 当我们想要修改某个变量的时候, 我们可以创建一个指向该
变量地址的指针变量。传递数据使用指针, 而无须拷贝数据。类型指针不能进行偏移和运算。Go语言中的指针操作非常简单, 只需要记住两个符号:&(取地址)和*(根据地址取值)。 - 取地址操作符
&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址指向的值。 - 变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
- 对变量进行取地址
&操作, 可以获得这个变量的指针变量。 - 指针变量的值是指针地址。
- 对指针变量进行取值
*操作, 可以获得指针变量指向的原变量的值。
- 对变量进行取地址
指针地址和指针类型
每个变量在运行时都拥有一个地址, 这个地址代表变量在内存中的位置。Go语言中使用
&字符放在变量前面对变量进行"取地址"操作。 Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型, 如:*int、*int64、*string等。取变量指针的语法:
ptr := &v- v: 代表被取地址的变量, 类型为T
- ptr: 用于接收地址的变量, ptr的类型就为*T, 称做T的指针类型。*代表指针。
| |
- 输出:
| |
指针取值
- 在对普通变量使用
&操作符取地址后会获得这个变量的指针, 然后可以对指针使用*操作,也就是指针取值。
| |
- 输出:
| |
指针传值
| |
- 输出:
| |
new和make
Go语言中
new和make是内建的两个函数, 主要用来分配内存。new
new是一个内置的函数,它的函数签名:func new(Type) *Type,Type表示类型,new函数只接受一个参数, 这个参数是一个类型.*Type表示类型指针,new函数返回一个指向该类型内存地址的指针。new函数不太常用, 使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。
| |
- 输出:
| |
make也是用于内存分配的,区别于new, 它只用于slice、map以及chan的内存创建, 而且它返回的类型就是这三个类型本身, 而不是他们的指针类型, 因为这三种类型就是引用类型, 所以就没有必要返回他们的指针了。make函数的函数签名func make(t Type, size ...IntegerType) Typemake函数是无可替代的, 我们在使用slice、map以及channel的时候, 都需要使用make进行初始化, 然后才可以对它们进行操作。
| |
- 输出:
| |
new 与 make 的区别
- 二者都是用来做内存分配的。
make只用于slice、map以及channel的初始化, 返回的还是这三个引用类型本身。new用于类型的内存分配, 并且内存对应的值为类型零值, 返回的是指向类型的指针。