这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
Java转go选手,这是第二次学习go语言,希望借这个机会再把GO语言基础查漏补缺一下,
第一次写markdown,格式出错望多多包涵
1 简介
1.1 什么是 Go 语言
- Golang = C 语言 + GC + 协程 + 反射 + interface;总而言之它更像C语言,也结合了很多其他编程语言的特性。
- 完善的工具链,丰富的标准库
- 支持的目标平台多,支持交叉编译;
- 高性能,高并发;
1.2 谁在用 Go
云原生,微服务,大数据
1.3 字节为什么用 Go
python性能问题,早期团队非java背景,内部rpc框架的推广
2 入门 Go
2.1 开发环境
1.goland(推荐)
2.Vscode带插件
2.2 基础语法 - Hello World & 变量
-
var 变量名字 类型 = 表达式
-
简短变量声明:
:=可以自动推断类型;
2.3 基础语法 - if
-
写法类似C++,if 条件语句 后面不需要跟括号
-
if后必须使用大括号。
2.4 基础语法 - 循环
- 没有while
2.5 基础语法 - switch
- 类似C,但不用 break;
2.6 基础语法 - 数组
很少用,通常用切片。
2.7 基础语法 - 切片
可变长的数组,一个slice是一个轻量级的数据结构,提供了访问数组子序列(或者全部)元素的功能,slice的底层确实引用一个数组对象。一个slice由三个部分构成:指针、长度和容量。指针指向第一个slice元素对应的底层数组元素的地址,要注意的是slice的第一个元素并不一定就是数组的第一个元素。长度对应slice中元素的数目;长度不能超过容量,容量一般是从slice的开始位置到底层数据的结尾位置。内置的len和cap函数分别返回slice的长度和容量。
内置的make函数创建一个指定元素类型、长度和容量的slice。容量部分可以省略,在这种情况下,容量将等于长度。
make([]T, len)
make([]T, len, cap) // same as make([]T, cap)[:len]
GO语言相比Java来说没有自带的栈堆等数据结构,很多都是由切片来完成的
比如:一个slice可以用来模拟一个stack。最初给定的空slice对应一个空的stack,然后可以使用append函数将新的值压入stack:
stack = append(stack, v) // push v
stack的顶部位置对应slice的最后一个元素:
top := stack[len(stack)-1] // top of stack
通过收缩stack可以弹出栈顶的元素
stack = stack[:len(stack)-1] // pop
slice可以很轻松地实现栈和堆的一些基本功能
如果你需要测试一个slice是否是空的,使用len(s) == 0来判断,而不应该用s == nil来判断。
2.8 基础语法 - map
一个map就是一个哈希表的引用,map类型可以写为map[K]V,其中K和V分别对应key和value。
即使有些元素不在map中也没有关系;如果一个查找失败将返回value类型对应的零值
使用 make 函数创建:
ages := make(map[string]int) // mapping from strings to ints
复制代码
注意:遍历一个 map 的顺序是完全随机的,如果要按顺序遍历key/value对,我们必须显式地对key进行排序,可以使用sort包的Strings函数对字符串slice进行排序。
2.9 基础语法 - range
对 slice 和 map 进行遍历的简约实现。
2.10 基础语法 - 函数
业务中常见带有两个返回参数,第二个通常是err。
2.11 基础语法 - 指针
Go语言的指针只能用来传值。
2.12 基础语法 - 结构体
Go 不是一门面向对象(OOD)的语言,因此,Go 并没有类(Class)或是其他类似概念,取而代之的,是同类语言中均拥有的结构体(Struct) 。
2.13 基础语法 - 方法
Go 没有类,但是你可以给类型绑定函数,这个绑定上去的函数就是方法。
其实对于非结构体的类型,也可以定义方法,这一个特性有点像扩展函数:
但是必须要求这个类型声明和方法的声明在同一文件内。
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
func main() {
f := MyFloat(-math.Sqrt2)
fmt.Println(f.Abs())
}
复制代码
与此处相同,调用一个方法时,也可以直接使用指针调用,方法接收到是值还是指针,由方法的声明决定,例如:
type Vertex struct {
X, Y float64
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func ScaleFunc(v *Vertex, f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
复制代码
对于上述方法,以下两种调用方式是等价的:
var v Vertex
v.Scale(5) // OK
p := &v
p.Scale(10) // OK
复制代码
此处同样可以理解为,由于在 Scale 的函数声明中,制定了接收 Vertex 的指针(也就是*Vertex),所以 go 会把 v.Scale(5) 解释成 (&v).Scale(5) 。
2.14 基础语法 - 错误处理
Go这样设计的原因是由于对于某个应该在控制流程中处理的错误而言,将这个错误以异常的形式抛出会混乱对错误的描述,这通常会导致一些糟糕的后果。当某个程序错误被当作异常处理后,这个错误会将堆栈跟踪信息返回给终端用户,这些信息复杂且无用,无法帮助定位错误。
正因此,Go使用控制流机制(如if和return)处理错误,这使得编码人员能更多的关注错误处理。
2.15 基础语法 - 字符串处理
string包下有很多实用的字符串处理操作
2.16 基础语法 - 字符串格式化
可以用%v对任意类型的变量进行打印
2.17 基础语法 - JSON 处理
主要是 Marshal 和 Unmarshal 做字符串和 struct 之间的转换
2.18 基础语法 - 时间处理
标准库
2.19 基础语法 - 数字解析
strconv.Parse${转换类型}
2.20 基础语法 - 进程信息
Pass
主要参考为 :
字节内部课:Go 语言上手 - 基础语法 Go语言圣经 博客:https://juejin.cn/post/7188806603154882618