文章目录
- 引子
 - 知识图谱
 - 包
 - 代理设置
 - 关键字
 - 数据类型
 - 变量
 - struct 和 interface
 - 控制语句
 - 字符串
 - 单引号、双引号、反引号
 - 数组与切片
 - 字典
 - make和new
 - json与yaml
 - 基本语法
 - 指针
 - Channel
 - defer
 - init函数
 - 类
 - error, panic, recover
 - channel与协程
 - 调试
 - 热加载
 - Gin的热加载
 - Iris的热加载
 
- 常用Golang框架
 - 常用链接
 - 开源项目
 
引子
玩腻了Python和Java的同学,可以试试Golang,换个口味。其实Golang已经流行好几年了,我们项目中2016年就在使用Golang了。但我一直没有时间去尝试,最近入手了一下,果然是香。
我最初看中它的是部署方便,代码保密性高于Java。目前看来,大部分后端程序都是可以用Golang开发的。
Golang适用场景:
- 网络编程:构建高性能的网络应用程序,如web服务器、API服务器
 - 并发编程:如消息队列、爬虫
 - 分布式系统:如etcd、Consul、ZooKeeper,支持RPC和序列化机制
 - 云计算:构建以docker和k8s为基础设施的云原生应用
 - 区块链:其实是一大应用,如Ethereum的Go语言客户端Geth
 - 数据库编程和系统编程:不弱于C/C++,编写底层工具,得益于Go和C的无缝衔接
 
总而言之,后端网络和分布式编程是Golang的主战场,主打高性能、高并发和云原生。
知识图谱




包
Golang都是按包名调用,和文件名无关。通常包名和所在的目录名称相同。
import (
	. "fmt" // 调用时可以去掉包名
	_ "go-common/app/infra/notify/conf" // _操作只是为了简单的调用包里的init函数(),不能引用其它函数
	xsql "go-common/library/database/sql" // 别名,防止冲突
)
 
包名为main,且其中包含main()函数的文件能编译成可执行文件,该文件未必一定要放在main目录下。
代理设置
goproxy
 https://goproxy.io/zh/
七牛云
 https://goproxy.cn
阿里云
 https://mirrors.aliyun.com/goproxy/
$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct
$ go env -u GOPROXY //取消代理
 
关键字
Golang一共25个关键字:
break、case、chan、const、continue、default、defer、else、fallthrough、for
func、go、goto、if、import、interface、map、package、range、return
select、struct、switch、type、var
此外,rune 和 byte 是Go 语言中仅有的两个类型别名。
 它的定义:
 type rune = int32
 type byte = uint8
 
rune相当于Java里的char类型。
数据类型
• 布尔类型:bool
 • 整型:int8、byte、int16、int、uint、uintptr 等
 • 浮点类型:float32、float64
 • 复数类型:complex64、complex128
 • 字符串:string
 • 字符类型:rune,本质上是 uint32
 • 错误类型:error
此外,Go 语言也支持以下这些复合类型:
 • 指针(pointer)
 • 数组(array)
 • 切片(slice)
 • 字典(map)
 • 通道(chan)
 • 结构体(struct)
 • 接口(interface)
变量
new(T): 根据类型T分配内存;设置内存为0;返回内存的指针
 make只用于初始化 slice,map 和 channel
 makeSlice := make([]int, 5, 10)
struct 和 interface
空结构体struct{}一般用作占位符
 空接口interface{}代表任意类型
控制语句
- if 语句的判断条件都没有了括号包起来,还可以前置写变量初始化语句,类似于 for 循环
 - 左花括号{必须与 if 或者 else 处于同一行
 
字符串
//字符相关的转化一般用 strconv 包
 v1 := “100”
 v2, err := strconv.Atoi(v1) // 将字符串转化为整型,v2 = 100
 v3 := 100
 v4 := strconv.Itoa(v3) // 将整型转化为字符串, v4 = “100”
避免[]byte和string的反复来回转换
单引号、双引号、反引号
- 单引号在 Golang 表示一个字符,使用一个特殊类型 rune 表示字符型。rune 为 int32 的别名,它完全等价于 int32,习惯上用它来区别字符值和整数值。rune 表示字符的 Unicode 码值
 - 双引号用来创建可解析的字符串字面量,支持转义,但不能用来引用多行。
 - 反引号用来创建原生的字符串字面量 ,这些字符串可能由多行组成,不支持任何转义序列。原生的字符串字面量多用于书写多行消息、HTML 以及正则表达式。
 
数组与切片
//定义数组
 var a [8]byte // 长度为 8 的数组,每个元素为一个字节 var b [3][3]int // 二维数组(9 宫格)
 var c [3][3][3]float64 // 三维数组(立体的 9 宫格)
 var d = [3]int{1, 2, 3} // 声明时初始化
 var e = new([3]string) // 通过 new 初始化
 var f = make([]string, 3) // 通过 make 初始化
 //初始化
 a := [5]int{1,2,3,4,5} b := […]int{1, 2, 3}
 //切片
 b := []int{} //数组切片 slice 就是一个可变长数组
 c := a[1:3] // 有点类似于 subString,或者 js.slice
 d := make([]int, 5) //make 相当于,new、alloc,用来分配内存
遍历删除数组:
var next *Element
for e := l.Front(); e != nil; e = next {
	next = e.Next()
	l.Remove(e)
}
 
字典
var testMap map[string]int testMap = map[string]int{
"one": 1, "two": 2, "three": 3,
}
//还可以这样初始化:
var testMap = make(map[string]int) //map[string]int{} testMap["one"] = 1
testMap["two"] = 2
testMap["three"] = 3
 
如果map的value较大,通常应该使用指针来存储,以避免性能问题,类似的还有channel,slice等。
make和new
- new()返回的永远是类型的指针,指针指向分配类型的内存地址;
 - make()返回值
 - new 可以分配任意类型的数据
 - slice、chan、map 只能用 make,本身就是指针。其他 make、new 都行
 
func new(Type) *Type
// 切片
make([]T, length, capacity)
 
json与yaml
基本语法
- 根据其首字母大小写来决定,如果属性名或方法名首字母大写
 
指针
指针在 Go 语言中有两个使用场景: 类型指针和数组切片。
 Go 语言中的类型指针不能进行偏移和运算。
 不同于C/C++,Go中可以返回局部变量的指针,因为Go编译器会对每个局部变量进行逃逸分析,会将这样的变量分配在堆上。
Channel
channel类似于消息队列,用于生产者和消费者间的通信,并适配两者的速度。
done := make(chan Result, 1) 
go func() {
	done <- Result{}
}()
result := <-done fmt.Println(result)
 
并行编程中,多个 goroutine 间采用生产者/消费者模型通信时,就用到channel。
defer
defer 流程有点像 Java 里面的 finally,保证了一定能执行,我感觉底层也是 goto 的 实现吧。在后面跟一个函数的调用,就能实现将这个 xxx 函数的调用延迟到当前函 数执行完后再执行。
常用来做资源清理、关闭文件、解锁、记录执行时间。
 禁止函数退出的几种方法:
func main() {
    defer func() { for {} }()
}
func main() {
    defer func() { select {} }()
}
func main() {
    defer func() { <-make(chan bool) }()
}
 
init函数
主要作用:
- 初始化不能采用初始化表达式初始化的变量。
 - 程序运行前的注册。
 - 实现sync.Once功能。
 - 其他
 
init函数的主要特点:
- init函数先于main函数自动执行,不能被其他函数调用;
 - init函数没有输入参数、返回值;
 - 每个包可以有多个init函数;
 - 包的每个源文件也可以有多个init函数,这点比较特殊;
 - 同一个包的init执行顺序,golang没有明确定义,编程时要注意程序不要依赖这个执行顺序。
 - 不同包的init函数按照包导入的依赖关系决定执行顺序。
 
类
没有 class 这个关键字,Go 里面的类是用结构体来定义的:
type Student struct { 
	id uint
	name string 
	male bool 
	score float64
}
 
//没有构造函数,但是可以用函数来创建实例对象,并且可以指定字段初始化,类似于 Java 里面的静态工厂方法
func NewStudent(id uint, name string, male bool, score float64) *Student {
	return &Student{id, name, male, score} }
func NewStudent2(id uint, name string, male bool, score float64) Student { 
	return Student{id, name, male, score}
}
 
error, panic, recover
channel与协程
channel可以理解为消息队列,通信操作符 <- 的箭头指示数据流向。
- 向 channel 中添加数据(channel<-data);
 - 从 channel 中读取数据(data<-channel);
 - data<-channel, 从 channel 中接收数据并赋值给 data
 - <-channel,从 channel 中接收数据并丢弃
 - 关闭 channel(通过 close()函数实现)
 
channel 分为有缓冲 channel 和无缓冲 channel,无缓冲 channel 在读和写的过程中是都会阻塞。
var ch = make(chan int) // 无缓冲
var ch = make(chan int,10)  // 有缓冲,实际上是一个阻塞队列,长度为0, 容量为10
 
func longTask(signal chan int) {
  // 不带参数的 for
  // 相当于 while 循环
  for {
    // 接收 signal 通道传值
    v := <- signal
 
    // 如果接收值为 1,停止循环
    if v == 1 {
      break
    }
 
    time.Sleep(1 * Second)
  }
}
 
func main() {
  // 声明通道
  sig := make(chan int)
 
  // 异步调用 longTask
  go longTask(sig)
 
  // 等待 1 秒钟
  time.Sleep(1 * time.Second)
 
  // 向通道 sig 传值
  sig <- 1
 
  // 然后 longTask 会接收 sig 传值,终止循环
}
 
调试
- 安装delve:
 
go install github.com/go-delve/delve/cmd/dlv
- 然后在vscode中配置launch.json:
 
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [       
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${file}"
        }
    ]
}
 
- 打开要调试的文件,如main.go,然后F5即可启动调试
 
热加载
Gin的热加载
安装fresh: github.com/pilu/fresh
Iris的热加载
安装rizla:
go install github.com/kataras/rizla@latest
然后命令行执行:
rizla main.go
常用Golang框架
- Gin : web 框架
 - Echo : High performance, minimalist Go web framework
 - fresh : About Build and (re)start go web apps after saving/creating/deleting source files
 
常用链接
- Go的官方文档
 - Go的中文api文档
 - Go中文社区网站
 - 地鼠文档
 - uber Go编码规范
 - Go高性能编程
 
开源项目
- 开源内容管理系统ponzu
 - 开源内容管理:perkeep
 - buttercms
 - 开源社区系统bbs-go
 - 一个基于 Beego 开发的可切换模板的 BBS 社交博客系统
 










![[管理与领导-7]:新任管理第1课:管理转身--从技术业务走向管理 - 管理常识1](https://img-blog.csdnimg.cn/img_convert/ad37af93a77d51cf25752adf117357df.jpeg)








