我自己的Go语言学习笔记。
仓库地址
LxnChan/go-learn
Go语言总体结构
每个Go语言项目应至少包含main.go和go.mod文件,前者是入口文件,后者是项目名称、所使用Go版本和需要引入的模块的列表。
main.go应由最少两个结构:包名和main函数组成:
1 2 3 4 5
| package main
func main() {
}
|
可以使用import关键字引入包:
1 2 3 4 5 6 7
| package main
import "fmt"
func main() { fmt.Println("Hello world.") }
|
其中函数结构体的花括号不能单独一行,必须和func等关键字处于同一行。
所有逻辑必须在函数内部。
变量、常量和赋值
变量
1 2 3 4 5 6 7 8
| var name string
var name string = "XiaoMing"
var name = "XiaoMing"
|
如果变量从未被引用过则编译器可能会报错;
不能同时不写数据类型又不赋值。
也可以在函数中短定义变量,基本结构变量名:=值:
1 2 3 4 5 6 7 8 9
| package main
import "fmt"
func main() { if nbhl := 999; nbhl < 5 { fmt.Println("not true") } }
|
常量
运算符
算术运算
+、-、*、/。
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main
import "fmt"
func main() { var a int = 10 var b int = 90 fmt.Println(a + b) fmt.Println(a - b) fmt.Println(a * b) fmt.Println(a / b) }
|
除四则运算还有一个取余数:
1 2 3 4 5 6 7 8 9 10
| package main
import "fmt"
func main() { var a int = 5 var b int = 2 fmt.Println(a % b) }
|
输出结果是1。
自增自减
比较(关系运算)
>/>=:大于和大于等于;</<=:小于和小于等于;!=/==:不等于和等于;
逻辑运算
下表列出了所有Go语言的逻辑运算符。假定 A 值为 True,B 值为 False。
&&:逻辑 AND 运算符:如果两边的操作数都是 True,则条件 True,否则为 False,(A && B) 为 False;||:逻辑 OR 运算符:如果两边的操作数有一个 True,则条件 True,否则为 False,(A || B) 为 True;!:逻辑 NOT 运算符。如果条件为 True,则逻辑 NOT 条件 False,否则为 True,!(A && B) 为 True。
流程控制
If
基本结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package main
import "fmt"
func main() { if 条件表达式 { 语句 } else if 条件表达式 { 语句 } else { 语句 } if nbhl := 999; nbhl < 5 { fmt.Println("not true") } else { fmt.Println("666") } }
|
If 语句可以简写为:
1 2 3 4 5
| var a bool=true if a { fmt.Println("True.") }
|
即=true部分可忽略。
For
1 2 3 4 5 6 7 8 9 10
| package main
import "fmt"
func main() { for i:=0; i<5; i++ { fmt.Println(i) } }
|
break跳出循环
执行到break时立即停止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package main
import "fmt"
func main() { var c int for { c++ fmt.Println(c) if c == 100 { break } } }
|
Switch
1 2 3 4 5 6 7 8 9 10 11
| switch 变量 { case 值1: 语句 case 值2: 语句 case 值3, 值4, 值5: 语句
default: 语句 }
|
延迟执行
1 2 3 4 5 6 7 8 9 10 11 12 13
| package main
import "fmt"
func main() { fmt.Println("Start...") defer fmt.Println("1") defer fmt.Println("2") defer fmt.Println("3") fmt.Println("end") }
|
数组
定义方法:
1 2 3 4 5 6 7 8 9
| var arrCity = [2] string {"Beijing", "Tianjin"}
var arrPoint = [...] int {99, 98, 99, 100, 92}
var arrPeople = [...]string{1: "小王", 3: "18", 7: "女"} fmt.Println("姓名为", arrPeople[1], ",年龄为", arrPeople[3], ",性别为", arrPeople[7])
fmt.Println(len(arrPoint))
|
多维数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
var arrRobot = [...][4]string{ {"1a96", "2a13", "3a16", "4a19"}, {"1a96b", "2a13b", "3a16b", "4a19b"}, } fmt.Println(arrRobot[1][2])
for i := 0; i <= len(arrRobot)-1; i++ { fmt.Println(i) for j := 0; j <= 3; j++ { fmt.Println(j) fmt.Println(arrRobot[i][j]) } }
|
获取多维数组元素数量
给定数组,求获取{7, 3, 6}的元素数量。
1 2 3 4
| var arrTmp = [][]int{{1, 5}, {7, 3, 6}, {3, 5}}
len(arrTmp[1])
|
切片
切片的底层本质就是一种数组。
1 2
| var sliceAtr = [] int {9, 6, 6}
|
基于数组得到切片
数组或切片的截取操作。截取操作有带 2 个或者 3 个参数,形如:[i:j] 和 [i:j:k],假设截取对象的底层数组长度为 l。在操作符 [i:j] 中,如果 i 省略,默认 0,如果 j 省略,默认底层数组的长度,截取得到的切片长度和容量计算方法是 j-i、l-i。操作符 [i:j:k],k 主要是用来限制切片的容量,但是不能大于数组的长度 l,截取得到的切片长度和容量计算方法是 j-i、k-i。
1 2 3 4
| var arrNtr = [...]string{"Natsuki", "Torari", "Klier"} sliceNtr := arrNtr[0:3] fmt.Println(sliceNtr)
|
Make函数构造切片
1 2 3 4
|
var sliceMrr = make([]int, 5, 10) fmt.Println(sliceMrr)
|
元素数量是指里面会被初始化进去多少个元素,容量则是指底层数组的最大容量。容量值可省略,省略时容量=元素数量。
上例中输出值应为[0 0 0 0 0],因为初始化进去了五个元素,都是对应类型的默认值。
Map(映射)
- 声明Map并初始化
其中键值对数量可以省略。
1 2 3 4 5 6
| var mapCity = make(map[string]string, 8) fmt.Println(mapCity) mapCity["Beijing"] = "001" mapCity["Shanghai"] = "002" fmt.Println(mapCity)
|
- 取出键值
1
| fmt.Println(mapCity["Shanghai"])
|
- 判断键值是否存在
1 2 3 4
|
val, ok := mapCity["ShenYang"] fmt.Println(ok, val)
|
Map 遍历
使用for...range...结构来遍历map:
1 2 3 4
| for k, v := range mapCity { fmt.Println(k, v) }
|
如果不需要接收其中一个值可以这么写:
1 2 3 4 5 6 7
| for k, _ := range mapCity { fmt.Println(k, v) } for _, v := range mapCity { fmt.Println(k, v) }
|
获取切片容量
Map 排序
待完成。
指针
Go语言中指针只有两种操作:取地址(&)和根据地址取值(*)。
1 2 3 4 5 6 7 8 9 10 11
| package main
import "fmt"
func main() { a := 666 b := &a fmt.Println(b, *b) }
|
在上例中,a的类型为int,则b(指针)的类型为*int。
指针传值
可以通过指针传值修改变量值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package main
import "fmt"
func main() { var c int = 996 modify1(c) fmt.Println(c) modify2(&c) fmt.Println(c) }
func modify1(x int) { x = 955 return }
func modify2(y *int) { *y = 1055 return }
|