day1 Go语言回顾| 青训营笔记

51 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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 处理

主要是 MarshalUnmarshal 做字符串和 struct 之间的转换

2.18 基础语法 - 时间处理

标准库

2.19 基础语法 - 数字解析

strconv.Parse${转换类型}

2.20 基础语法 - 进程信息

Pass

主要参考为 :

字节内部课:Go 语言上手 - 基础语法

Go语言圣经

博客:https://juejin.cn/post/7188806603154882618