这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
一、本堂课重点内容:
1.Golang特点
2.Golang基础语法
二、详细知识点介绍:
1.Go语言的特点:
(1)高性能、高并发
性能媲美c++、Java,且不需要第三方库来提供高性能服务,仅用标准库即可实现高性能、高并发开发
(2)语法简单、学习曲线平缓
语法与c语言相似度高,且摒弃了一些繁杂的c语言的语法,容易上手
(3)丰富的标准库
Golang有如python一样丰富的标准库,且具有很高的稳定性与兼容性的保障,降低了开发的成本
(4)完善的工具链
无论是编译、代码格式化、文档管理、错误检查、代码补充提示,都有对应的工具,且还有完整的代码测试框架
(5)静态链接
Golang编译结果默认静态链接。只需要拷贝编译后唯一一个可执行文件,即可部署运行,方便快捷
(6)快速编译
Golang具有静态语言中几乎最快的编译速度
(7)跨平台
Golang能在多种不同的操作系统下运行,包括安卓、Linux、Windows、Macos以及一些奇奇怪怪的设备上运行,还能配置交叉编译环境
(8)垃圾回收
Golang配有垃圾回收机制,在写代码时无需考虑内存的分配与释放
2.Go语言基础语法(易忘点):
(1)声名
Go语言主要有四种类型的声明语句:var、const、type和func,分别对应变量、常量、类型和函数实体对象的声明。
(2)Slice
Slice(切片)代表变长的序列,序列中每个元素都有相同的类型。一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已。
内置的append函数用于向slice追加元素:
var x []int
x = append(x, 1)
x = append(x, 2, 3)
x = append(x, 4, 5, 6)
x = append(x, x...) // append the slice x
fmt.Println(x) // "[1 2 3 4 5 6 1 2 3 4 5 6]"
(3)Map
内置的make函数可以创建一个map:
a.ages := make(map[string]int)
b.ages := map[string]int{
"alice": 31,
"charlie": 34,
}
使用内置的delete函数可以删除元素:delete(ages, "alice")
Map的迭代顺序是不确定的,并且不同的哈希函数实现可能导致不同的遍历顺序。
(4) JSON
JavaScript对象表示法(JSON)是一种用于发送和接收结构化信息的标准协议。
Go语言对于这些标准格式的编码和解码都有良好的支持,由标准库中的encoding/json、encoding/xml、encoding/asn1等包提供支持
基础类型可以通过JSON的数组和对象类型进行递归组合。一个JSON数组是一个有序的值序列,写在一个方括号中并以逗号分隔;一个JSON数组可以用于编码Go语言的数组和slice。一个JSON对象是一个字符串到值的映射,写成一系列的name:value对形式,用花括号包含并以逗号分隔;JSON的对象类型可以用于编码Go语言的map类型(key类型是字符串)和结构体。例如:
boolean true
number -273.15
string "She said "Hello, BF""
array ["gold", "silver", "bronze"]
object {"year": 1980,
"event": "archery",
"medals": ["gold", "silver", "bronze"]}
考虑一个应用程序,该程序负责收集各种电影评论并提供反馈功能。它的Movie数据类型和一个典型的表示电影的值列表如下所示。
type Movie struct {
Title string
Year int json:"released"
Color bool json:"color,omitempty"
Actors []string
}
var movies = []Movie{
{Title: "Casablanca", Year: 1942, Color: false,
Actors: []string{"Humphrey Bogart", "Ingrid Bergman"}},
{Title: "Cool Hand Luke", Year: 1967, Color: true,
Actors: []string{"Paul Newman"}},
{Title: "Bullitt", Year: 1968, Color: true,
Actors: []string{"Steve McQueen", "Jacqueline Bisset"}},
// ...
}
将一个Go语言中类似movies的结构体slice转为JSON的过程叫编组(marshaling)。编组通过调用json.Marshal函数完成,返回一个编码后的字节slice,包含很长的字符串
使用json.Unmarshal函数来将JSON格式的字符串解码为字节slice
(5) 匿名函数
函数字面量允许我们在使用函数时,再定义它。通过这种技巧,我们可以改写之前对strings.Map的调用:strings.Map(func(r rune) rune { return r + 1 }, "HAL-9000")
(6)可变参数
在声明可变参数函数时,需要在参数列表的最后一个参数类型之前加上省略符号“...”,这表示该函数会接收任意数量的该类型参数。
func sum(vals ...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}
(7)Deferred函数
你只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法。当执行到该条语句时,函数和参数表达式得到计算,但直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。你可以在一个函数中执行多条defer语句,它们的执行顺序与声明顺序相反。
通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。释放资源的defer应该直接跟在请求资源的语句后。
(8)Panic异常
Go的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、空指针引用等。这些运行时错误会引起painc异常。
一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine(可以先理解成线程,在第8章会详细介绍)中被延迟的函数(defer 机制)。随后,程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。
不是所有的panic异常都来自运行时,直接调用内置的panic函数也会引发panic异常;panic函数接受任何值作为参数。当某些不应该发生的场景发生时,我们就应该调用panic。比如,当程序到达了某条逻辑上不可能到达的路径
(9)Recover捕获异常
通常来说,不应该对panic异常做任何处理,但有时,也许我们可以从异常中恢复,至少我们可以在程序崩溃前,做一些操作。举个例子,当web服务器遇到不可预料的严重问题时,在崩溃前应该将所有的连接关闭;如果不做任何处理,会使得客户端一直处于等待状态。如果web服务器还在开发阶段,服务器甚至可以将异常信息反馈到客户端,帮助调试。
如果在deferred函数中调用了内置函数recover,并且定义该defer语句的函数发生了panic异常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运行,但能正常返回。在未发生panic时调用recover,recover会返回nil。
三、课后个人总结:
通过本堂课的学习,本人对Golang的优点、基础语法在理论上有了基础的了解,接下来即将进入工程项目实战课程的学习,争取通过实践加深对Golang的理解