这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
语言优势
语法简单,学习周期短
Go语言在C语言的基础上弃用了许多繁琐的格式和功能相似的关键字,包括if和for的括号、while和do while以及分号等,在熟悉go的语法之后能明显体会到开发时带来的随意和惬意。
//死循环
for {
fmt.Println("loop")
break
}
//带索引循环
for j := 7; j < 9; j++ {
fmt.Println(j)
}
Go语言却又很好地继承了大部分基础语法,甚至作了更好的优化,比如if条件后面必须跟花括号,这就让不同人的代码风格更加相似,代码格式也更加清晰,还有switch-case的灵活优化。
t := time.Now()
switch { //区别于C语言只能带常量表达式
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
标准库丰富(高稳定,高性能,持续优化)
Go语言的标准库提供了清晰的构建模块和公共接口,包含 I/O 操作、文本处理、图像、密码学、网络和分布式应用程序等,并支持许多标准化的文件格式和编解码协议。
静态链接,单一文件运行
Go语言本地库文件默认通过静态链接调用,在编译时以编译系统内包含的共享库作为资源进行链接,在运行时不再依赖系统的共享库,从而解决了对宿主系统动态链接的共享库版本有要求而带来的问题。
编译速度快,比C++快
Go语言的编译速度是快于C++的,其原因有以下几点:
- 使用了import的引用管理方式
- 没有模板的编译负担
- 1.5版本后的自举编译器优化
- 更少的关键字
据统计,Go语言只有25个关键字,而即使是C语言也有32个关键字。
基本语法
定义变量
Go语言的变量类似python和js,却又是C这类的强类型语言。
单一变量创建
var a int = 10 // 定义类型
var b = 10 // 自动判定类型
c : = 10 // 省略var
多变量创建
var a, b, c = 10, 20, 30 // 可以各自不同类型
定义数组
a := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
b := a[5] // 指定位置索引
c := a[6:10] // 联系位置索引
fmt.Println(b) // 5
fmt.Println(c) // [6,7,8,9]
关于切片
切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型,内部结构包含地址(指向数组的指针)、大小和容量。
// slice:表示目标切片对象
// 开始位置:对应目标切片对象的索引
// 结束位置:对应目标切片的结束索引
// slice [开始位置 : 结束位置]
var a = [3]int{1, 2, 3}
fmt.Println(a, a[1:2]) // 其他用法包括a[1:] & a[:1] & a[:](原生) & a[0:0](重置)
创建切片
// 声明字符串切片
// 声明一个字符串切片,切片中拥有多个字符串
var strList []string
// 声明整型切片
// 声明一个整型切片,切片中拥有多个整型数值
var numList []int
make()动态创建切片
// 其中 Type 是指切片的元素类型
// size 指的是为这个类型分配多少个元素
// cap 为预分配的元素数量,这个值设定后不影响 size,只是能提前分配空间,降低多次分配空间造成的性能问题
make( []Type, size, cap )
a := make([]int, 2)
b := make([]int, 2, 10)
fmt.Println(a, b) // [0,0] [0,0]
fmt.Println(len(a), len(b)) // 2 2
append()为切片添加元素
append()函数需要将自身作为参数传入,使a指向新的切片,究其原因,是当切片发生扩容时整个切片的地址都将整体改变。
var a []int
a = append(a, 1) // 追加1个元素
a = append(a, 1, 2, 3) // 追加多个元素
a = append(a, []int{1,2,3}...) // 追加一个切片
var a = []int{1,2,3}
a = append([]int{0}, a...) // 在开头添加1个元素
a = append([]int{-3,-2,-1}, a...) // 在开头添加1个切片
字典map
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m) // map[one:1 two:2]
fmt.Println(len(m)) // 2
fmt.Println(m["one"]) // 1
fmt.Println(m["unknow"]) // 0
range
range是go中的一种遍历方式,类似于迭代器,返回索引key和索引值value,可以遍历本质上还是for循环。
range 应用于不同数据类型时,返回 (索引, 值) 或 (键, 值),下表是对应的结构:
| type | 1st value | 2nd value |
|---|---|---|
| string | index | s[index] |
| array/slice | index | s[index] |
| map | key | m[key] |
| channel | element |
x := []string{"a", "b", "c"}
//忽略value,只返回key
for v := range x {
fmt.Println(v) //prints 0, 1, 2
} //输出:0\n 1\n 2\n
//忽略key,只返回value,用_占位,该用法最为常见
for _, v := range x {
fmt.Println(v) //prints a, b, c
} //输出:a\n b\n c\n
//返回key和value
for k, v := range x {
fmt.Println(k, v)
} //输出:0 a\n 1 b\n 2 c\n
结构体
Go语言中,结构体属性名首字母大写可以使用相关函数直接序列化和反序列化。
type People struct {
Name string
Age int
}
json.Marshal() //序列化(*自动Base64编码)
json.Unmarshal() //反序列化
函数
Go语言中函数用func定义,可以返回多个值,一般业务场景会返回结果和执行状态。
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
func main() {
res := add(1, 2)
fmt.Println(res) // 3
v, ok := exists(map[string]string{"a": "A"}, "a")
fmt.Println(v, ok) // A True
}
今日分享内容到此为止,课程相关内容并未全部展示,总的来说Go语言的设计很有趣,其本身也十分强大。