P1 为什么要学习go
go语言设计之初就考虑到多核CPU了,编译好执行,有几个核就跑满几个核
etcd代替zookeeper
P2 课上所有物料介绍
typora的笔记里偏好设置,图片到当前的.assets文件夹
预习的地方
P3 安装GO开发环境
安装到显眼的目录
出现提示就说明安装成功了
P4配置GOPATH
GO是编译型语言,有很多依赖需要编译进去,就需要配置一个工作区,workspace的概念。就是把所有源代码写到这个目录下面。
GOPATH是一个环境变量,表明你写的项目的存放路径,也就是工作目录。
这个目录当成是今后作为源代码开发的工作目录
新建一个系统变量
现在在windows上会有一个默认路径。需要更新一下
在GOpatch下创建三个目录,所有源代码放在src下,用于编译的包放在pkg,可执行文件在bin下
把这个bin加到PATH变量里去
可以go env查看变量。
go root是安装go.exe文件所在的目录
go path是代码的位置
go arch平台的意思
P5 GO目录项目目录结构介绍
下面是适合个人的
go的第三方包,一般是用域名,因为域名是唯一的。
可以写个自己的域名 ,通常一般用github上的域名
写用户名
企业里 一般是这么用,公司内部一般会有代码托管的网址+什么组+每个组的具体项目
也可以这么写
P6 安装VSCode编辑器
推荐vscode,goland收费
先安装一个中文插件
安装一个go插件
P7 编写第一个Go语言程序
vscode不会自动保存,需要设置一下auto save
编写代码的是会有一些弹窗,一些自动补全的插件,可以直接install all
会安装到gopath下的bin目录
如果因为网络失败,可以下载现成的
如何去编译
windows平台的可执行文件就是exe
如果想在其他路径编译,只能加src往后的路径
这个时候,在哪里执行的命令,就在哪里生成exe文件
可以指定编译出来的文件名
go run相当于执行一个脚本文件
go install相当于2部事情,先执行go build,然后会把生成的二进制文件拷贝到gopath的bin目录
跨平台编译,windows平台编译一个linux平台 的文件
编译出来 了linux平台的程序
P8 变量申明
所有的.go文件都需要package申明,说明这个文件属于哪个包,如果代码在main包,相当于你的代码最终会编译成可执行文件,想要编译就一定要func main函数,程序的入口,main函数没有参数也没有返回值,语句只能放到函数里,不能像python一样随便写
go语言是静态类型语言,定义的时候一定要说明类型
批量声明
go语言中变量声明了就必须使用到,否则编译不过
go有自己的format工具 go fmt
go语言推荐小驼峰命名变量,下面绿色的线代表不怎么规范
几个print的差别,没有换行
P9 变量赋值
全局变量可以声明了不使用,因为可能别的代码里会使用,但是在main里声明的就必须使用,否则编译不过去
声明变量的同时进行赋值,绿色代表不怎么推荐,因为有类型推导
类型推导
简短变量声明,就只能在函数里使用
**有些变量不想要的时候可以赋值给_下划线 **
同一个作用域不能声明两个一样的变量
P10 常量和iota
常量是在程序运行过程中,恒定不变的量
还可以批量声明,如果批量申明常量没有写值,某一行没有写等号,默认就和上一行一致
iota是go里的常量计数器,只能在常量的表达式中使用。
iota在const关键字出现的时候将被重置为0.const中每新增一行常量声明将使iota加一次
iota可以实现一个枚举
答应你0,1,3
插队声明
每新增一行iota+1
1左移10位,相当于1的10次方=1024,往左移20位,1的20次方,1024kb=1mb
P11 整形
整形分,带符号的整数和无符号的整数,u开头的都是无符号的
特殊整形,uintptr一般用来存 内存地址,
go语言无法直接定义二进制数,0开头是8进制数,0x开头是16进制数
%d表示用10进制数来代替
八进制数077转成10进制就是63
16进制数是0到f,%o八进制,%x16进制,%b二进制数
通常给文件设置权限会用到8进制
声明一个int8类型的变量
P12 浮点型和布尔值
const常量float32最大值是后面那么多
go里面浮点数本来就是不精确的,推荐就是64
强制定义32位的
但是不同类型的变量是不能够直接赋值
布尔值默认是false
%v,不管什么值都可以打出来
fmt总结5
%T查看类型,%v查看值,b二进制,d10进制,o8进制,x16进制,s字符串
加一个井号会代表描述符
P14 字符串操作
go里的字符串只能用双引号
字符串在go里只能用双引号
打印反斜线
多行的字符串
反引号里的是原样输出,之前字符串的转义符就可以不使用了
拼接字符串
分割
是否包含
前后缀
字串出现的位置
b最后出现的位置
拼接
P15 字符串修改和类型转换
打印成字符
abc一个英文字符称为byte,中文和其他语言位rune类型,rune类型就是一个类型的别名
rune类型代表utf-8类型
字符串不能修改,要能修改只是转换成另外一种类型的变量,:=相当于重新赋值,双引号代表字符串,单引号代表字符。切片里保存的就是字符。
hello如果是字符串类型,分解下来里面有5个字符,go语言里单引号代表字符
看看单引号和双引号的区别,rune类型其实是int32类型的别名,一个中文占3个字节,一个字节占8bit,3*8=24,为什么是int32,因为utf-8有前缀
可以把值打印出来
双引号就是字符串,单引号就是字符,英文来说,用ascii码表的就能表示,只占1个字节,如果对应中文,需要3个bytes,也可以强制转换成byte,实际上就是uint8
布尔类型不能和其他类型互相转换
int转float,只有整形和浮点型可以转换,还有字符串和切片
P16 if判断和for循环
多个if判断
这样声明的age变量只在if条件判断里
初始值可以被省略掉
初始语句和结束语句都可以省略掉
死循环
键值循环,专门用来遍历数组,切片
索引和字符
P17 内容回顾
GOpath就是写go代码的工作区
goroot是你安装go.exe的执行文件
go在函数外面,只能写关键字开头
函数内部定义的变量,必须使用
死循环
可以求字符串长度
%d 数字,%c字符
直接打印一个变量是索引
无符号代表的数字范围大一些,正负数
不同类型的float也不能比较
byte是int8 ,rune是int32
字符串都使用utf-8编码,rune类型就是int32,要用4个字节存储
二进制数在go里是不可以直接定义的。0开头是8进制,0x开头是16进制
可以格式化打印,%o8进制,%x16进制
P18 switch和goto
for循环里使用break跳出循环
跳出某一次循环
大量判断可以使用switch,简化变量和具体的值做比较
现在就整个跳出了
P19 运算符
go里面 ++和–代表单独的语句,语句不能放在等号右边作为赋值
按位与,按位或
异或,两位不一样是1
左移
右移
位与可以在计算ip和权限
P20 数组
go里的数组类似列表,但是要定义长度和里面的数据类型
长度为3的数组,类型是bool
长度是数组的类型一部分
类型是长度3布尔型的数组,也就是长度是类型 的一部分
如果不初始化,默认元素就是0值,布尔值就是false,整型和浮点型就是0,字符串就是空
初始化的几种方式
还可以用指定索引的方式
根据索引的方式,遍历数组
长度为3,每个元素里都是长度为2的int类型的数组
多维数组的遍历
P21 数组练习题
P22 切片1
数组的长度是固定的,是申明的一部分
切片定义好了就初始化
nil相当于空,在go里代表没有开辟内存空间
之前是自己定义切片,然后做初始化。由一个已经存在的数组做切片
一些自定义的切片方式
切片的容量是底层数组的容量,底层的数组动第一个元素到最后元素的数量
第二章是容量是从切片的第一个元素到最后一个元素
切片指向了一个底层的数组,切片的程度就是它元素的个数。
切片的容量是底层数组从切片的第一个元素到最后一个元素的数量。
支持扩容
之前自己定义的切片,其实底层是一个对应长度的数组,然后把数组封装一下返回
切片再切片
3开始只有13这个元素,所以长度是1,容量也是1
切片是一个引用类型,都指向了一个底层的数组,数组变了,切片就变了
P23 切片的本质
make函数是用来创建切片的
5个元素全是0的切片
传两个值就是,长度5,容量也是5
长度为0,容量为10的切片
切片 就是一个框,框住了一块连续的内存,go比较偏底层,所以就是只能保存一些相同类型的元素,其他语言设计的时候已经给你实现了一片内存存不同类型的数据
切片只能和nil值比较,nil值代表切片没有底层数组
nil也就是相当于你创建了两个切片,但是底层数组还不知道
判断切片一定要用len去判断是否是空的
切片支持索引遍历和range遍历
vscode可以设置变量
选择go
输入prefix里的东西,会把body里的内容输出到文本里
P24 append和copy
调用append函数,必须使用原来切片的变量接收返回值。
切片底层的数组是不变的,容量改变了,只能说明指向了另外的数组。所以append追加的时候,原来的底层数组放不下的时候,Go就会把底层数组换一个
源码位置
append,扩容的策略就是首先判断,新申请容量大于2倍的旧容量,最终容量就是新申请 容量,否则判断,如果旧切片小于1024,最终容量就是旧容量的2倍。
如果旧切片大于1024,就是循环累加容量,一次加1/4。
如果存的是int和string处理的方式还不一样。
ss…三个点代表拆开
修改值,copy相当于把a1的值都拿出来放到另外的地方。
go语言里没有删除切片元素的专用犯法
切片是不存值的,底层数组才是存值的,所以容量还是3
现成的一个数组,长度2,容量3
x1是数组,s1是指向x1的切片,
s1 = append(s1[:1],s1[2:]…),把x1第0个元素,和最后一个拼接在一起,相当于5往前移一位
因为数组对应一块连续的内存,所以原来3也就是变成了5
其实make 5 的时候,长度5就已经初始化为5个元素在里面了,追加就往后去追加
容量扩容后就是20
P25 append再补充
s1[0:1]左闭右开
相当于框出来的往前移一格
P26 指针和make及new
指针是int类型
*根据地址取值,int星号int代表int类型的指针
**a是一个int类型的值,指向一个内存地址
b是一个指针,b存的值就是a的内存地址
b也有一个内存地址就是&b
**
对变量进行取址&操作,可以获得这个变量的指针变量
new和make都是用来创造指针的
无效的内存地址,a这个变量其实是空的指针
用 new 来申请一个内存地址,有了内存地址才能赋值
make也是用来分配内存的,区别于new,只用于slice、map以及chan类型的内存创建。
go的指针只要认识到一个英文的取址符号&,一个根据地址求值的符号。*
P27 map
map在go里表示映射关系
申明后一定要初始化,否则没有开辟内存空间
预估一个map的容量,避免运行中动态扩容
一般约定一个ok来接收布尔值
如果不存在这个key,就拿到对应类型的0值
for range 遍历map
删除key,如果删除不存在的,也就是什么都不干
查看go的delete函数
可以在这个网站上查看帮助
rand.seed随机数,time.now()当前的时间,
先打印上面的
要想排序,先把所有的key拿出来放到切片里去,对切片做一个排序,遍历切片,从map里找对应key的值,这样就能实现一个有顺序的遍历
map和切片类型做一个组合,做一个更复杂的数据类型
make做一个切片,切片类型是map,长度为0,切片里就没有元素,就不是0
改成1试试
长度0的时候,里面没元素,报index out of range,长度为1的时候,map没有初始化
需要对map做初始化,切片和map都需要做初始化
值为切片类型的map
前提是一个map
P28 函数
函数是一段代码的封装
参数跨域匿名也可以不匿名,返回值的名字可以在函数内部直接使用,命名返回值相当于在函数中申明一个遍历,相当于在函数内部已经申明了一个遍历叫ret
上面的没有有命名返回值就一定要显式返回,下面使用了命名返回值就可以不写return ret,因为不写也知道return ret
返回值可以有多个
参数可以简写,两个参数如果都是int,类型一致,可以将前面参数的类型省略
可变长参数,y …int,代表y可以传多个值,都是int类型
go函数没有默认参数概念