该笔记是学习青训营内部课程内容结合自己在网络上的搜索其他学习资料编写的,适合零基础小白使用!!!!
Go简介
- Go语言(或 Golang)是Google开发的开源编程语言
- go是非常年轻的一门语言,它的主要目标是“兼具Python 等动态语言的开发速度和C/C++等编译型语言的性能与安全性”
- Go语言为并发而生
Go安装与环境配置
1. 下载安装链接:
2. 找到合适的位置解压,解压后如如下图
3. 环境变量配置
将bin目录的完整路径加入到环境变量的系统变量path中。新建目录作为GOPATH,该目录下新建三个文件夹分别为bin,pkg,src,同时在环境变量系统变量中新建GOPATH变量,值为新建的GoPATH目录的完整路径。其中 bin 文件夹用于存放在编译项目时,生成的可执行文件,pkg文件夹用于存放在编译项目时,生成的包文件,src 文件夹用于存放编写的代码
4. 安装验证
打开命令行提示符,输入go env,go version验证
Go基础
1. go命令
- go env用于打印Go语言的环境信息。
- go run命令可以编译并运行命令源码文件。
- go build命令用于编译我们指定的源码文件或代码包以及它们的依赖包生成可执行文件。
- go doc命令可以打印附于Go语言程序实体上的文档。我们可以通过把程序实体的标识符作为该命令的参数来达到查看其文档的目的。
- go test命令用于对Go语言编写的程序进行测试。
- go list命令的作用是列出指定的代码包的信息。
2. go变量,常量与数据类型
- go变量声明方式: var 变量名 变量类型
单个声明:
var name string
var age int
var isOk bool
批量声明:
var (
a string
b int
c bool
d float32
)
- go变量赋值方式: var 变量名 类型 = 表达式
var name string = "pprof.cn"
var sex int = 1
- 类型推导: 有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化
var name = "pprof.cn"
var sex = 1
- 在函数内部,可以使用更简略的 := 方式声明并初始化变量
package main
import (
"fmt"
)
// 全局变量m
var m = 100
func main() {
n := 10
m := 200 // 此处声明局部变量m
fmt.Println(m, n)
}
- 数据类型
1. 值类型
- 整型
整型分为以下两个大类:
按长度分为:int8、int16、int32、int64
对应的无符号整型:uint8、uint16、uint32、uint64
其中,uint8就是我们熟知的byte型,int16对应C语言中的short型,int64对应C语言中的long型。
- 浮点型
Go语言支持两种浮点型数:float32和float64。这两种浮点型数据格式遵循IEEE 754标准: float32 的浮点数的最大范围约为3.4e38,可以使用常量定义:math.MaxFloat32。 float64 的浮点数的最大范围约为 1.8e308,可以使用一个常量定义:math.MaxFloat64。
- 复数
complex64和complex128
复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部和虚部为64位。
- 布尔值
Go语言中以bool类型进行声明布尔型数据,布尔型数据只有true(真)和false(假)两个值。
注意:
布尔类型变量的默认值为false。
Go 语言中不允许将整型强制转换为布尔型.
布尔型无法参与数值运算,也无法与其他类型进行转换。
- 字符串
Go语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、float32、float64 等)一样。 Go 语言里的字符串的内部实现使用UTF-8编码。 字符串的值为双引号(")中的内容,可以在Go语言的源码中直接添加非ASCII码字符
字符串转义符,Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。
| 转义 | 含义 |
|---|---|
| \r | 回车符(返回行首) |
| \n | 换行符(直接跳到下一行的同列位置) |
| \t | 制表符 |
| ' | 单引号 |
| " | 双引号 |
| \ | 反斜杠 |
-
byte与rune字符类型 Go 语言的字符有以下两种:
- uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
- rune类型,代表一个 UTF-8字符。
-
数组Array
- 数组:是同一种数据类型的固定长度的序列。
- 数组定义:var a [len]int,比如:var a [5]int,数组长度必须是常量,且是类型的组成部分。一旦定义,长度不能变。
- 长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型。
- 数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1 for i := 0; i < len(a); i++ { } for index, v := range a { }
- 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
- 数组是值类型,赋值和传参会复制整个数组,而不是指针。因此改变副本的值,不会改变本身的值。
- 支持 "=="、"!=" 操作符,因为内存总是被初始化过的。
- 指针数组 [n]*T,数组指针 *[n]T。
-
结构体struct Go语言中通过struct来实现面向对象。
结构体的定义
使用type和struct关键字来定义结构体,具体代码格式如下:
type 类型名 struct {
字段名 字段类型
字段名 字段类型
…
}
1.类型名:标识自定义结构体的名称,在同一个包内不能重复。
2.字段名:表示结构体字段名。结构体中的字段名必须唯一。
3.字段类型:表示结构体字段的具体类型。
举个例子,我们定义一个Person(人)结构体,代码如下:
type person struct {
name string
city string
age int8
}
同样类型的字段也可以写在一行
2. 引用类型
- slice -- 序列数组(最常用)
- map -- 映射
- chan -- 管道
3. go运算符
- 算术运算符
| 运算符 | 描述 |
|---|---|
| + | 相加 |
| - | 相减 |
| * | 相乘 |
| / | 相除 |
| % | 求余 |
- 关系运算符
| 运算符 | 描述 |
|---|---|
| == | 检查两个值是否相等,如果相等返回 True 否则返回 False。 |
| != | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 |
| 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 | |
| >= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 |
| < | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 |
| <= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 |
- 逻辑运算符
| 运算符 | 描述 |
|---|---|
| && | 逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。 |
| ll | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。 |
| ! | 逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。 |
- 位运算符
| 运算符 | 描述 |
|---|---|
| & | 参与运算的两数各对应的二进位相与。(两位均为1才为1) |
| l | 参与运算的两数各对应的二进位相或。(两位有一个为1就为1) |
| 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。(两位不一样则为1) | |
| << | 左移n位就是乘以2的n次方。“a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。 |
| >> | 右移n位就是除以2的n次方。“a>>b”是把a的各二进位全部右移b位。 |
- 赋值运算符
| 运算符 | 描述 |
|---|---|
| = | 简单的赋值运算符,将一个表达式的值赋给一个左值 |
| += | 相加后再赋值 |
| -= | 相减后再赋值 |
| *= | 相乘后再赋值 |
| /= | 相除后再赋值 |
| %= | 求余后再赋值 |
| <<= | 左移后赋值 |
| >>= | 右移后赋值 |
| &= | 按位与后赋值 |
| l= | 按位或后赋值 |
| ^= | 按位异或后赋值 |
4. go流程与循环控制
条件语句if
Go 编程语言中 if 语句的语法如下:
可省略条件表达式括号。
持初始化语句,可定义代码块局部变量。
代码块左 括号必须在条件表达式尾部。
if 布尔表达式 {
在布尔表达式为 true 时执行
} else if 布尔表达式 {
在此之前的布尔表达式为false,此布尔表示式为true时执行
} else {
在此之前的布尔表达式为false时执行
}
else if语句可以有多个
x := 0
if n := "abc"; x > 0 { // 初始化语句未必就是定义变量, 如 println("init") 也是可以的。
println(n[2])
} else if x < 0 { // 注意 else if 和 else 左大括号位置。
println(n[1])
} else {
println(n[0])
}
不支持三元操作符(三目运算符) "a > b ? a : b"。
条件语句switch
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上直下逐一测试,直到匹配为止。switch分支表达式可以是任意类型,不限于常量。可省略 break,默认自动终止。
Go 编程语言中 switch 语句的语法如下:
switch var1 {
case val1:
...
case val2:
...
default:
...
}
变量 var1 可以是任何类型,而 val1 和 val2 则可以是同类型的任意值。类型不被局限于常量或整数,但必须是相同的类型;或者最终结果为相同类型的表达式。 您可以同时测试多个可能符合条件的值,使用逗号分割它们,例如:case val1, val2, val3
循环语句for
for循环是一个循环控制结构,可以执行指定次数的循环。
Go语言的For循环有3种形式,只有其中的一种使用分号。
for init; condition; post { }
for condition { }
for { }
init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
for语句执行过程如下:
①先对表达式 init 赋初值;
②判别赋值表达式 init 是否满足给定 condition 条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。
s := "abc"
for i, n := 0, len(s); i < n; i++ { // 常见的 for 循环,支持初始化语句。
println(s[i])
}
n := len(s)
for n > 0 {
println(s[n])
n--
}
for {
println(s)
}
循环语句range
range类似迭代器操作,返回 (索引, 值) 或 (键, 值)。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
for key, value := range oldMap {
newMap[key] = value
}
| 1st value | 2nd value | |
|---|---|---|
| string | index | s[index] |
| array/slice | index | s[index] |
| map | key | m[key] |
| channel | element |
可忽略不想要的返回值,或 "_" 这个特殊变量。
package main
func main() {
s := "abc"
// 忽略 2nd value,支持 string/array/slice/map。
for i := range s {
println(s[i])
}
// 忽略 index。
for _, c := range s {
println(c)
}
// 忽略全部返回值,仅迭代。
for range s {
}
m := map[string]int{"a": 1, "b": 2}
// 返回 (key, value)。
for k, v := range m {
println(k, v)
}
}
循环控制语句goto,continue,break
- goto配合标签使用,标签名区分大小写,定义后若不使用会造成编译错误,跳出循环到指定位置继续执行
- continue、break分别用于跳出本次循环,跳出这个循环语句,然后按顺序继续执行