我从17年开始写go代码,到现在断断续续写了四年有余,其实比较惭愧,目前对go的认识非常浅薄。
究其原因,一个是我使用go的开发只是工作上粘合使用,每年写go代码的时间也不足1个月,基本上是在原有框架上做一些新功能的开发。得益于过去多年在laravel上的经验,看api文档和谷歌能力还是不错的,socket交互、orm、mongodb、k8s client-go等东西上手并不难,看半天基本上也就明白了如何使用。
二个是我工作中心更多是放在k8s这套系统以及偏网络方向上,虽然也是研发,更多是行业和架构层面的。
从今年下半年开始,我的工作重心转到了go的开发上来,而我个人也倾向于使用go作为我未来的主力开发语言。接下来这段时间我会记录更多关于 go 的基础知识。
这篇文章没什么重点,记录一些只言片语吧。
一、学习书籍
当遇到看不懂的内容时,有可能是作者的思考回路和我们的有差别。
不必纠结,跳过去,当看到同样内容不同作者的描述,你可能会豁然开朗。
入门:
入门时要注重理解go的设计理念和语言机制(Language Mechanics),
语言机制包括Go语言的句法、数据结构、解耦。
- 《Go 程序设计语言》——许式伟译(英文原版翻译的,感觉细看浪费时间,快速浏览/后期针对性溯源就行。)
- 《Go 语言编程》——许式伟(感觉适合基础入门,以补全理论概念铺垫为主,实战代码可以后期再看)
熟练:
熟练时要理解软件设计,研究并发,Go协程(Goroutine)、数据竞赛、多个channel和不用模式和用模式下的操作
高级:
了解基本单元测试、表测试、自测试等发测试方法,以及常见的标准等,还有各种包(Packages)。
更多选看:
二、Go 概念只言片语
这一部分大多来自 《Go 语言编程》——许式伟
2. 1 一些网站:
2. 2 基础类型:
2. 3 组合类型:
-
指针
-
数组
-
slice切片
-
map(哈希表/字典)
-
通道channel
-
struct 结构体
-
interface接口
2. 4 流程控制:
- 选择
- 条件语句 if else
- 选择语句 switch case/select
- break continue fallthrough
- 循环 for 和 range
- 跳转 goto
2. 5 函数调用:
- 大小写区分:
- 小写字母开头的函数只在本包内可见,大写字母开头的函数才能被其他包使用。
- 这个规则也适用于类型和变量的可见性。
-
函数可以像普通变量一样被传递或使用
-
不定参数:
func myfunc(args ...int)
func Printf(format string, args ...interface{})
-
多返回值:
func (file *File) Read(b []byte) (n int, err Error)
-
匿名函数/闭包:
- 闭包内可以引用父方法的变量
- 父方法为闭包提供绑定的计算环境(作用域)
-
错误处理:
-
type error interface {
Error() string
}
-
defer
- 先进后出的原则,延迟执行,一般用于文件、通道chan关闭、错误处理等。
- panic/recover
- init()和main()
2. 6 类型系统:
2. 7 面向对象:
-
构造函数,以NewXXX 来命名,表示“构造函数”
func NewRect(x, y, width, height float64) *Rect {
return &Rect{x, y, width, height}
}
-
有继承,直接在struct引用父struct就ok了(匿名组合)。可以重写覆盖父方法。
-
方法/变量的可见性,用大小写表示public/private。
-
接口,隐式声明。
2. 8 并发编程:
使用场景:
实现方式:
协程:
goroutine:
2. 9 网络编程:
- Socket
- http
- rpc
- json
- net/http包
2. 10 安全编程:
2.11 代码规范:
2. 12 工程构建与命令行:
命令行主要完成以下这几类工作:
-
代码格式化
-
代码质量分析和修复
-
单元测试与性能测试
-
工程构建
-
代码文档的提取和展示
-
跨平台开发、编译
2. 13 高阶话题
2. 14 其它
方法与函数的区别:
函数是指不属于任何结构体、类型的方法,也就是说函数是没有接收者的;
方法是有接收者的,我们说的方法要么是属于一个结构体的,要么属于一个新定义的类型的。
方法在定义的时候,会在func
和方法名之间增加一个参数,这个参数就是接收者,这样我们定义的这个方法就和接收者绑定在了一起,称之为这个接收者的方法。
type person struct {
name string
}
func (p person) String() string{
return "the person name is "+p.name
}
用户自定义类型,也应该实现Len()和Cap()方法。
Go语言的符号(symbol)一样,以大写字母开头的常量/函数在包外可见。
方法func
常量const(字面量)
变量var,赋予一内存块名字,该内存块保存特定的数据类型。可以匿名(返回值,等号左侧填_)
指针:保存了另一个变量内存地址的变量。
&
,取址操作符。
*
,解引用操作符。
如果一个函数/方法返回超过4/5个值,最好使用一个切片/指向结构体的指针来传递,成本较低。
三、Go 实操笔记
这一部分大多来自:《Go 语言学习笔记》——雨痕
四、hello world
main.go
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
初始化go module
go mod init kelu.org/apptest
go mod tidy
go build
这样会生成一个 apptest 的可执行文件。