环境配置
go env -w GOPROXY=https://goproxy.cn,direct
GOPROXY=https://goproxy.cn
下载所有依赖可以使用go mod download
go mod tidy命令更新go.mod中的依赖关系
导包时候加入项目名 相对路径
语言基础
整型:
int8 有符号 8位整型 (-128 到 127) 2的0次幂到7 后面以此类推
int16 有符号 16位整型 (-32768 到 32767)
int32 有符号 32位整型 (-2147483648 到 2147483647)
int64 有符号 64位整型 (-9223372036854775808 到 9223372036854775807)
字符串转义:
\r 回车符(返回行首) \n 换行符(直接跳到下一行的同列位置) \t 制表符 ’ 单引号 " 双引号 \ 反斜杠
类型转换:
Go语言中只有强制类型转换,没有隐式类型转换
流程控制
goto(跳转到指定标签)
数组
数组的长度是固定的并且数组长度属于类型的一部分
切片
var name []T
切片中左闭右开 长度high-low
a[2:] // 等同于 a[2:len(a)]
a[:3] // 等同于 a[0:3]
a[:] // 等同于 a[0:len(a)]
make([]T, size, cap)使用make创建切片
判断一个切片是否是空的,要是用len(s) == 0
拷贝前后两个变量共享底层数组,对一个切片的修改会影响另一个切片的内容,这点需要特别注意。
函数
定义:
func 函数名(参数)(返回值){
函数体
}
在函数内部定义的变量无法在外部使用
匿名函数就是没有函数名的函数
闭包
闭包=函数+引用环境
变量f是一个函数并且它引用了其外部作用域中的x变量,此时f就是一个闭包。 在f的生命周期内,变量x也一直有效。
recover()必须搭配defer使用
map
map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。
定义:
map[KeyType]ValueType
map类型的变量默认初始值为nil,需要使用make()函数来分配内存。语法为:
make(map[KeyType]ValueType, [cap])
其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。
指针
&(取地址)和*(根据地址取值)
Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string
make也是用于内存分配的,区别于new,它只用于slice、map以及channel的内存创建
结构体
使用new关键字对结构体进行实例化,编程结构体指针
取结构体相当于又new了一下结构体
键值对对结构体进行初始化,也可以对结构体指针进行键值对初始化
什么时候应该使用指针类型接收者
需要修改接收者中的值
接收者是拷贝代价比较大的大对象
保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。
结构体标签
Tag是结构体的元信息,可以在运行的时候通过反射的机制读取出来
ID int json:"id" //通过指定tag实现json序列化该字段时的key
Gender string //json序列化是默认使用字段名作为key
name string //私有不能被json包访问
初始化函数执行顺序init()优于main()
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
函数体
}
Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。
指针类型的接收者由一个结构体的指针组成,由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的。这种方式就十分接近于其他语言中面向对象中的this或者self。
什么时候应该使用指针类型接收者
需要修改接收者中的值
接收者是拷贝代价比较大的大对象
保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。
接口
定义:
type 接口类型名 interface{
方法名1( 参数列表1 ) 返回值列表1
方法名2( 参数列表2 ) 返回值列表2
}
在 Go 语言中一个类型只要实现了接口中规定的所有方法,那么我们就称它实现了这个接口。
那实现了接口又有什么用呢?一个接口类型的变量能够存储所有实现了该接口的类型变量。
一个接口的所有方法,不一定需要由一个类型完全实现,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现。
通过在结构体中嵌入一个接口类型,从而让该结构体类型实现了该接口类型,并且还可以改写该接口的方法。
// reverse 结构体中嵌入了Interface接口
type reverse struct {
Interface
}
空接口是指没有定义任何方法的接口类型。因此任何类型都可以视为实现了空接口。也正是因为空接口类型的这个特性,空接口类型的变量可以存储任意类型的值。
通常我们在使用空接口类型时不必使用type关键字声明,可以像下面的代码一样直接使用interface{}。
var x interface{} // 声明一个空接口类型变量x
空接口的应用
空接口作为函数的参数
使用空接口实现可以接收任意类型的函数参数。
空接口作为map的值
使用空接口实现可以保存任意值的字典。
注意:我们不能对一个空接口值调用任何方法,否则会产生panic。
可以通过定义结构体来实现接口,然后将结构体指针赋值给接口变量m,这个m就可以调用接口的任何方法