Go语言基础——基础语法总结 | 青训营笔记

98 阅读7分钟

这是我参与「第五届青训营 」笔记创作活动的第1天

一. GO语言简介

1.1 GO语言特点

(1)高性能、高并发

内嵌高并发支持,不需要第三方库来开发应用,标准库即可。

(2)语法简单、学习曲线平缓

基于C语言,并作了大量简化,比如去掉不需要的表达式括号、只有一层循环等,上手快。 image.png
上图中仅用10行代码即可实现支持静态文件访问的高并发、高性能的服务器。

(3)丰富的标准库

标准库即可满足大部分开发需求,而且稳定。

(4)完善的工具链

编译、代码格式化、错误检查等;还内置了完整的单元测试框架。

(5)静态链接

只需要考虑编译后的唯一一个可执行文件即可部署运行

(6)快速编译

(7)跨平台

(8)垃圾回收

1.2 GO基础语法

(1)Hello World

image.png

程序框架:包名(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(不初始化):
image.png
②写入kv对:
image.png
③通过k取v:
image.png
④删除kv对:
image.png
⑤判断k是否存在于map:
image.png
⑥创建并初始化map(不需要make): image.png

(9)range

可以对切片或者map进行更简单的遍历,类似于java中的增强for循环;
①遍历数组切片:
image.png
其中i为下标,num为value;如果不需要下标,用_占位
②遍历map:
image.png
可以只遍历key

(10)函数

①变量类型后置,返回值后置:
image.png
②可以返回多个值,第一个为值结果,第二个为错误信息:
image.png

(11)指针

指针用途有限,主要用于对常用参数进行修改
image.png
上面的函数只是传值,不会对实参本身有变化;下面的函数用指针可以实现+2;
在调用参数为指针的函数的时候,需要传入指针: image.png

(12)结构体

定义:带类型的字段的集合
image.png
①结构体初始化三种方式:
image.png
也可以只创建结构体,不传参: image.png
②可以用 . 进行读写结构体参数: image.png
③函数参数可以为结构体,有指针和非指针两种方式:
image.png
非指针主要用来判断,指针参数的函数可以对结构体值进行读写,避免大结构体拷贝的开销

(13)结构体方法

结构体除了有参数,还可以有自己的方法:
①格式: image.png
②调用方法: image.png

(14)错误处理

Go可以清楚的知道哪个函数出现了错误
①函数定义:返回值要有两个,第二个为err:
image.png
表示如果存在就返回值和nil,如果不存在就返回nil和错误信息
②函数调用:需要有两个值来接收返回值,并通过判断err是否为nil来判断是否存在:
image.png
以上代码还可以简化,接收返回值和判断可以同时放到if里:
image.png

(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代表任意类型的数据,不需要自己区分:
image.png
%+v可以更详细的输出结果,%#v则更为详细,以结构体为例:
image.png
③%.2f,表示对浮点数保留两位小数:
image.png

(17)json处理

①结构体中保证每个变量以大写开头:
image.png
如果json格式不是大写字母开头的类型,而是小写,就需要在响应变量后面加上tag:json:"age",注意tag是用反引号包住的,此时变量定义依然是大写开头
②序列化:marshal
image.png
序列化后的json是byte数组,需要用string强转变为字符串
③marshalindent:可以对json数据做更多处理:第二个参数表示给每个json变量添加前缀,第三个参数表示换行等操作
image.png
表示把序列化结果buf换行显示
④反序列化:unmarshal
image.png
表示把buf反序列化赋值给b

(18)时间处理

导入time包
①获取当前时间:time.now
②构造时间变量: image.png
③获取年月日时分秒:
image.png
③按照某种格式去格式化一个时间变量:
image.png
④时间相减:结果依然是时分秒的单位
image.png
⑤把时分秒的单位转换成分钟或者秒:注意和获取时分秒区分,这个是加s的
image.png
⑥parse(A,B):把B按照A的格式创建一个时间变量
image.png
⑦获取时间戳:
image.png

(19)数字和字符串的相互转换

导入strconv包
①parsefloat:
image.png
把浮点型字符串转换为浮点型数字,64是位
②parseint:
image.png
整型字符串转整型数字,10是进制,64是位
image.png
如果第二个参数为0,表示自动推断字符串的进制,然后转为10进制,比如上图字符串为16进制
③Atoi:
快速把10进制整型字符串和整型数字互相转换:
image.png
会判断参数的合法性

(20)进程信息

①os.orgs:获取命令行参数 ,返回一个数组,第一个值为运行文件的绝对路径:
image.png
②os.getenv:获取系统环境变量的值:
参数:key - 系统环境变量名
返回:系统环境变量的值
image.png
③os.setenv:设置环境变量
输入对应的key-value字符串,返回error信息
image.png
④exec.command:快速获取子进程,获取其输入输出
image.png