这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
一、本堂课重点内容:
本堂课分为三大板块。
- 第一大板块,介绍了什么是Go语言,以及独特的优势。
- 第二大板块,介绍了Go语言基本语法。
- 第三大板块,使用三个demo示例带着学员在实践中掌握Go语言的基本语法。
二、详细知识点介绍:
Go语言介绍:
Go语言特点
- 高性能、高并发
- 简单、易于上手
- 静态编译
- 跨平台
- 自动GC
Go语言基本语法:
基本数据类型
Go语言基本数据类型有
- 整数
- 浮点数
- 布尔类型
- 复数
- 字符串
变量声明
Go语言变量声明时,使用var声明语句,且变量类型一般放在变量名后面
var 变量名字 类型 = 表达式
同时Go语言支持自动类型推断,当我们省略变量类型不写时,Go语言会自动根据表达式的值推断出变量的类型。
比如var a = 1,编译器会根据1推断出变量a的类型为int
声明常量时,只需要将var 改为 const 即可
例如 const 常量名字 类型 = 表达式
简短变量声明
简介
简短变量声明是在函数内部,用来声明和初始化局部变量的一种声明方式。
声明形式
名字 := 表达式
特点:
- 只能用于局部变量。
- 必须保证简短变量声明符号
:=的左边的变量,起码有一个未被声明。
作用
- 广泛用于大多数局部变量的声明和初始化
注意事项
var 变量声明符号 和 简短变量声明符号 := 不能一起使用。
例如
// 错误
var m := make(map[string]int)
// 正确
var m = make(map[string]int)
运算符
Go中的运算符以及运算符优先级与C/C++中类似,就不再补充。
但需要注意的是Go可以通过 “+” 直接进行字符串拼接操作(string在Go中是内置类型)。
流程控制语句
Go中的控制流语句极为简单。
对于条件控制语句只有 if、if-else 一种, 且与C++、Java语言的主要区别就在于判断条件是否有括号。
if condition {
// code
}
对于循环控制语句同样只有 for 语句一种,只要区别仍然是判断条件的括号,以及新的死循环表示方式。
// 死循环
for {
// code
}
// 条件循环
for a; b; c {
// code
}
数组
介绍
Go里面的数组与C++和Java中的数组类似,都支持下标随机访问,但也有着同样的问题。
数组的长度都是固定的,一旦声明之后,就没有办法改变,由此引出了切片类型。
数组声明
生成一个长度为numSize,指定数据类型的数组
数组名 [numSize]数据类型
不指定长度,直接初始化数组
数组名 := []数据类型 {值1,值2,值3}
这种方式声明的数组的大小与初始化的值的数量一致。
切片
介绍
- 切片长度是可变的,超出容量后会自动扩容,类似于Java中ArrayList
- 切片支持切片操作,比如
切片名[1:3]会获取切片中下标1-2的元素(前开后闭) - 通过copy函数,可以实现切片快速拷贝
切片声明
切片声明依靠make函数
var 切片名 = make([]数据类型,切片大小)
常用操作示例
var a = make([]int, 3)
a[0] = 0
a[1] = 1
a[2] = 2
// 切片
fmt.Print(a[:2]) // 0 1
// 拷贝
var b = make([]int, len(a))
copy(b,a)
// 追加
a = append(a, 3, 4, 5)
map
介绍
- 键值对存储,类似于Python中的字典
- map中的键值对无序存储
map 声明
map声明同样要依靠make
// [] 中的是map键的类型,外边的是map值的类型
var a = make(map[数据类型A]数据类型B)
常用操作
// 创建map
var m = make(map[string]int)
// 添加键值对
m[k] = r
// 获取键值对
// r要查找的值,找不到为默认值
// ok 是布尔值,如果在map中查找到就是true,反之false
r, ok := m[k]
fmt.Println(r, ok)
// 删除map中键值对
delete(m,k)
range遍历方式
简介
for循环的迭代遍历方式
数组迭代遍历
// 数组迭代遍历
nums := []int {1, 2, 3, 4, 5}
for i, v := range nums {
// i 代表当前元素下标
// v 代表当前元素值
fmt.Println(i, v)
}
// 输出结果
// 0 1
// 1 2
// 2 3
// 3 4
// 4 5
map迭代遍历
// map 迭代遍历
m := make(map[string]int)
m["a"] = 1
m["b"] = 2
m["c"] = 3
for k, v := range m {
// k 代表当前键值对的Key
// v 代表当前键值对的Value
fmt.Println(k, v)
}
// a 1
// b 2
// c 3
函数
简介
Go语言中函数与其他语言,比如C++、Java语言的不同,主要体现在两个方面。
- 独特的函数声明方式
- 多返回值
函数声明方式
func name(参数1、参数2) (返回值列表) {
函数体
}
多返回值
Go 中函数可以返回多个值,并可以直接将返回值赋值给多个值,常见于错误处理逻辑中。
例如
// json.Marshal函数可以将结构体进行序列化
// 函数返回值分别是序列化后的byte数组 buf 和 err异常
// 通过判断 err 是否为nil,可以知晓函数运行是否出错
buf, err := json.Marshal(request)
if err != nil {
log.Fatal(err)
}
指针
简介
Go中的指针相比于C、C++中功能较为单一,作用主要为对传入参数进行修改,因为Go中函数传参仍然采用了C语言中值传递的方式。
// 包变量n
var n int = 1
// 普通参数
func add(n int) {
n++
}
// 指针参数
func addPtr(n *int) {
*n++
}
func main() {
add(n)
fmt.Println(n) // 1 n的值未发生变化
addPtr(&n)
fmt.Println(n) // 2 n的值顺利++
}
结构体
简介
结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。
结构体类型声明
type user struct {
name string
password string
}
结构体变量声明
a := user{name:"lin", password:"1024"} //指定名称定义
b := user{"lin", "1024"} //顺序定义
结构体元素访问方式
// 通过.运算符访问来进行修改
a.name = ”li“
结构体方法
结构体方法类似于Java中的成员方法,且可以通过结构体的.运算符号直接调用
func (u user) checkPassword(password string) bool{
//code
}
func (u *user) resetPassword(password string) {
//code
}
func main() {
a := user{name: "wang", password: "1024"}
a.resetPassword("2048") // 调用,这里可以不同使用&
fmt.Println(a.checkPassword("2048")) // true
}
三、实践练习例子:
- 猜谜游戏
- 命令行在线字典
- SOCKS5代理服务器
四、课后个人总结:
收获
基本了解Go语言的特点以及基本语法,并通过demo练习的方式,对Go语言各种操作更加熟悉。
本章有什么知识点不容易掌握?
三个实践demo中用到了标准库中的API,对于这部分知识点不太熟悉。
五、引用参考:
- 字节内部课:走进 Go 语言基础语言
- Go语言圣经(中文版),前言 · Go语言圣经 (studygolang.com)