这是我参与「第五届青训营 」笔记创作活动的第1天
一. GO语言简介
1.1 GO语言特点
(1)高性能、高并发
内嵌高并发支持,不需要第三方库来开发应用,标准库即可。
(2)语法简单、学习曲线平缓
基于C语言,并作了大量简化,比如去掉不需要的表达式括号、只有一层循环等,上手快。
上图中仅用10行代码即可实现支持静态文件访问的高并发、高性能的服务器。
(3)丰富的标准库
标准库即可满足大部分开发需求,而且稳定。
(4)完善的工具链
编译、代码格式化、错误检查等;还内置了完整的单元测试框架。
(5)静态链接
只需要考虑编译后的唯一一个可执行文件即可部署运行
(6)快速编译
(7)跨平台
(8)垃圾回收
1.2 GO基础语法
(1)Hello World
程序框架:包名(main为程序入口包)、导入函数包、主函数
其中fmt为程序输入输出函数
(2)变量
变量类型:
GO为强类型语言,包括字符串、浮点型、布尔型、整型等类型
其中字符串为内置类型,可以直接用+拼接:
var a="initial"
g:=a+"foo"
字符串也可以直接用=比较
变量声明:
① var name=value,会自动根据value推断var类型
②name 类型=value,直接指定类型
③name:=value
常量声明:
const name=value
const name 类型=value
const没有确定的类型,是根据上下文自动判断的
(3)if-else
if后面没有小括号,并且条件后面必须有大括号
(4)循环
只有for循环,如果没有条件就是死循环;
for后面没有小括号,三个循环条件都可以省略;
continue、break正常使用
(5)switch
switch后不需要小括号;
默认不需要break自动退出;
switch条件可以是任意类型:字符串、结构体...
switch后面可以没有条件,不同的case代表不同的if条件来代替if else,case后的条件可以是范围值
(6)数组
长度固定,实际使用较少,更多用切片
(7)切片
可变长度数组
①用make创建切片:s:=make(【】string,3);创建时可以直接指定长度:c:=make(【】string,len(3))
②可以append添加元素:注意append的结果必须赋值给原数组:s=append{s,“d”},原理是切片是一个len+capacity+指针的结构,如果不指向原切片,那么扩容时指针就会指向新的切片
③可以用copy函数复制:copy(新切片,原切片)
④切片可以定范围取指:s【2:5】表示取出下标2到5的元素,包头不包尾
(8)map
完全无序,遍历是随机的
①make创建map(不初始化):
②写入kv对:
③通过k取v:
④删除kv对:
⑤判断k是否存在于map:
⑥创建并初始化map(不需要make):
(9)range
可以对切片或者map进行更简单的遍历,类似于java中的增强for循环;
①遍历数组切片:
其中i为下标,num为value;如果不需要下标,用_占位
②遍历map:
可以只遍历key
(10)函数
①变量类型后置,返回值后置:
②可以返回多个值,第一个为值结果,第二个为错误信息:
(11)指针
指针用途有限,主要用于对常用参数进行修改
上面的函数只是传值,不会对实参本身有变化;下面的函数用指针可以实现+2;
在调用参数为指针的函数的时候,需要传入指针:
(12)结构体
定义:带类型的字段的集合
①结构体初始化三种方式:
也可以只创建结构体,不传参:
②可以用 . 进行读写结构体参数:
③函数参数可以为结构体,有指针和非指针两种方式:
非指针主要用来判断,指针参数的函数可以对结构体值进行读写,避免大结构体拷贝的开销
(13)结构体方法
结构体除了有参数,还可以有自己的方法:
①格式:
②调用方法:
(14)错误处理
Go可以清楚的知道哪个函数出现了错误
①函数定义:返回值要有两个,第二个为err:
表示如果存在就返回值和nil,如果不存在就返回nil和错误信息
②函数调用:需要有两个值来接收返回值,并通过判断err是否为nil来判断是否存在:
以上代码还可以简化,接收返回值和判断可以同时放到if里:
(15)字符串操作
strings标准库包里有很多字符串方法,都可以用strings.即可调用:
contains(A,B):A是否包含B
count(A,B):A里有几个B
hasprefix(A,B):A是否以B开头
hassuffix(A,B):A是否以B结尾
index(A,B):B字符串在A中的索引
join(A字符串数组,B):把A数组每个元素用B连接起来
repeat(A,B):输出B个A
replace(A,B,C,-1):把A中的B换成C
split(A,B):用B把A截取,返回数组
tolower(A):把A全小写
toupper(A):把A全大写
len(A):A的长度,如果A是英文字母,就是字母个数;如果是汉字,不是汉字个数
(16)字符串格式化
①println:输出并换行
②printf:可以用%v代表任意类型的数据,不需要自己区分:
%+v可以更详细的输出结果,%#v则更为详细,以结构体为例:
③%.2f,表示对浮点数保留两位小数:
(17)json处理
①结构体中保证每个变量以大写开头:
如果json格式不是大写字母开头的类型,而是小写,就需要在响应变量后面加上tag:json:"age",注意tag是用反引号包住的,此时变量定义依然是大写开头
②序列化:marshal
序列化后的json是byte数组,需要用string强转变为字符串
③marshalindent:可以对json数据做更多处理:第二个参数表示给每个json变量添加前缀,第三个参数表示换行等操作
表示把序列化结果buf换行显示
④反序列化:unmarshal
表示把buf反序列化赋值给b
(18)时间处理
导入time包
①获取当前时间:time.now
②构造时间变量:
③获取年月日时分秒:
③按照某种格式去格式化一个时间变量:
④时间相减:结果依然是时分秒的单位
⑤把时分秒的单位转换成分钟或者秒:注意和获取时分秒区分,这个是加s的
⑥parse(A,B):把B按照A的格式创建一个时间变量
⑦获取时间戳:
(19)数字和字符串的相互转换
导入strconv包
①parsefloat:
把浮点型字符串转换为浮点型数字,64是位
②parseint:
整型字符串转整型数字,10是进制,64是位
如果第二个参数为0,表示自动推断字符串的进制,然后转为10进制,比如上图字符串为16进制
③Atoi:
快速把10进制整型字符串和整型数字互相转换:
会判断参数的合法性
(20)进程信息
①os.orgs:获取命令行参数 ,返回一个数组,第一个值为运行文件的绝对路径:
②os.getenv:获取系统环境变量的值:
参数:key - 系统环境变量名
返回:系统环境变量的值
③os.setenv:设置环境变量
输入对应的key-value字符串,返回error信息
④exec.command:快速获取子进程,获取其输入输出