这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
一、本堂课重点内容:
- Go语言的特点
- Go语言的基础语法
- 三个实战练习
二、详细知识点介绍:
Go语言的基本特征
- 高性能,高并发
- 强类型
- 完整的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
Go语言开发环境
1、安装Goland : go.dev/
2、选择适合的IDE:Vscode + Go插件 / GoLand
3、配置goproxy:加快第三方包的加载速度
Go语言基础语法
变量
在Go语言中数据类型分为4类 : 基础类型、复合类型、引用类型和接口类型
基础数据类型包括:数字、字符串和布尔型
注意:在Go中字符串是内置类型,可以通过加号直接拼接,也能够通过等于号直接去比较
复合数据类型:数组、结构体
引用类型:指针、切片、字典、函数、通道
如何声明一个变量
var name = type // 自动推导变量类型
var name type = value // 显式声明变量类型
name := type // 自动推导变量类型 (该种方式只能用于局部变量)
const name = type // 声明一个常量
数组
- 支持随机访问,长度固定的元素序列
- int float 默认值为0, string 默认值为 " " , bool 默认值为flase
// 声明一个数组
var a [5] int
var a [2][3] int
a := [5] int{1, 2, 3, 4, 5}
// 打印一个数组
fmt.Println(a)
流程控制语句
条件分支
- if 后无须括号,if 下的代码块必须添加大括号
if 1 > 0 {
fmt...
} else {
fmt...
}
循环分支
-
只有 for 循环 ,没有 while 循环,也没有 do - while 循环
-
拥有 continue 、break 关键字
// 死循环 for { fmt.Println("loop") break } // 常规循环 for i := 1; i < 10; i++ { fmt.Print(i) }
选择分支
Go语言的switch分支与Java有很大的不同
-
即使不添加break , Go中的case也不会往下继续执行
-
在switch后不加任何变量,这样可以支持你在 case 中写条件分支
-
switch可以支持任意变量
// x 可以为任意类型变量
var x = 1
switch x {
case 1:
fmt.Println(x)
case 2:
fmt.Println(x + 2)
}
// case 接条件分支
switch {
case x <= 1:
fmt.Println(x + 1)
case x > 2:
fmt.Println(x - 1)
}
切片
- 一个 slice 由三部分构成:指针、长度和容量
- slice在初始化的时候可以指定长度
- 指针指向第一个slice元素对应的底层数组元素地址
- 长度对应 slice 中元素的数目,长度不能超过容量
- 在进行append操作时,若容量不够的话则会扩容并返回一个新的slice
// 声明一个切片
strings := make([]string , 3)
// append 需要指定切片接收结果
strings = append(strings,"d")
// 切片操作
fmt.Println(strings[1:3]) // 1到3位置上的元素,不包括3
fmt.Println(strings[:3]) // 位置3前面的所有元素,不包括3
fmt.Println(strings[1:]) // 位置1后面的所有元素,包括1
map
- Key 必须是支持 == 运算符的数据类型
- 完全无序
// 声明一个map
map := make(map[Key]Value)
// 删除 map 中的映射
delete(map,key)
// 根据 key 获取值,contains 表示是否存在该映射关系
value,contains := map[Key]
range
- 遍历切片或数组时会返回两个值,第一个是index,第二个是value
- 遍历map时,第一个是key,第二个是value
- 可用下划线覆盖索引
nums := [7]int{1, 2, 3, 4, 5, 7, 8}
for _, j := range nums {
fmt.Println(i, j)
}
函数
- 函数原生支持返回多个值,在实际业务中通常返回两个值,一个是真正的返回结果,另一个是错误信息
func add(a int, b int) int {
return a + b
}
func contains(m map[string]int ,key string)(value int ,contain bool) {
v,ok := m[key]
return v,ok
}
指针
当调用一个函数时,会对其每一个参数值进行拷贝,如果一个函数需要更新一个变量,或者函数的其中一个参数实在太大,需要避免这种默认的拷贝,这种情况下可以用到指针
func add2(a *int) {
*a += 2
}
结构体
-
一种聚合数据类型
-
如果结构体成员名字是以大写字母开头的,那么该成员就是导出的;
// 声明一个结构体
type User struct {
name string
age int
}
// 声明一个User类型的变量tom
tom := User{name: "name", age: 15}
loosy := User{"name",15}
结构体方法
类似Java中的成员方法
func (user *User) upd(value string) {
user.name = value
}
func (user User) check(value string) bool {
return user.name == value
}
错误处理
对可能出错的函数同时返回两个结果以传递错误信息
func contains(m map[string]int, key string) (int, error) {
value, ok := m[key]
if !ok {
return 0, errors.New("non exist")
}
return value, nil
}
三、实践练习例子:
- 猜谜游戏
- 在线词典
- SOCKS5代理
四、课后个人总结:
- 通过本次学习了解了Go语言的特点以及掌握了Go语言的基础语法