Go is OpenSource
Go入门指南:https://learnku.com/docs/the-way-to-go
Go语言圣经(中文版):https://yar999.gitbook.io/gopl-zh
Go语言高级编程(Advanced Go Programming):https://chai2010.cn/advanced-go-programming-book/index.html
Python 和 Ruby 程序员:转到 Go 是因为他们并未放弃太多的表达能力,但是获得了性能,并且与并发共舞。
C++ 程序员:无法转到 Go 是因为他们经过艰辛的战斗才获得对其语言的精确控制能力,而且也不想放弃任何已经获得的东西。对于他们,软件不仅仅是关于让工作完成,而是关于用一个确定的方式完成。
Source: 为什么 Go 不被 C++ 程序员喜欢
祖传代码:
go version
// 单文件的使用方式 // hello.go // 执行:go run hello.go // 编译:go build hello.go // VS Code 请安装Go的插件,可以自动格式化,挺舒服的 // 包(package)的声明 // 「你必须在源文件中非注释的第一行指明这个文件属于哪个包」 // 如何理解包呢? package main // 引入包 import "fmt" // 声明变量,类型写在后面,没有赋予初值 // 变量需要预先声明,并且区分类型 var x int // 声明常量 // var 换成 const // 「常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型」 const Pi float64 = 3.14159265358979323846 // 常量用作枚举,这里没有显式指明数据类型,交给编译器自行推断 const ( Unknown = 0 Female = 1 Male = 2 ) // iota是一个特殊常量,借助它可以这样写 // 基本特点是会自增,一个小小语法糖,这里就不详述了 const ( MESSAGE = iota // 0 WARNING // 1 ERROR // 2 ) // 这是一个可选函数,如果有的话就会被首先执行 func init() { // 注意:"{" 不能写在单独的行上(我开始有点讨厌Go了,代码风格都要管) fmt.Println("Init") // 末尾不要分号 } // 程序的入口函数,为了构建一个完整的应用程序必须要有 func main() { fmt.Println("Hello, World!") x = 1 // 普通赋值 x++ // 支持自增自减 // 运算符:看起来和C差不多 // + - * / % ++ -- == != < > <= >= // && || ! & | ^ << >>(不支持"~"?) // += -= &= |=(类似这样的,也都支持) // 指针用:& * // 建议还是使用明确标示长度的数据类型 // 数据类型转换如下所示 var y int32 = int32(x) + 1 // 如果赋予初值,则可以不指定类型(我还是喜欢手动指定) var z = y + 1 // 同时声明多个变量 // var x1, x2 int32 // var c int // 声明 // c = 1 // 赋值 // 相当于 // var c int = 1 // 相当于 // c := 1 // 声明 & 赋值 // 多变量同时赋值 // v1, v2, v3 := x, y, z // 注意,使用冒号进行变量声明、赋值的形式,只能出现在函数体内部 // 同时声明多个不同类型的变量 // var ( // d1 int32 // d2 bool // ) fmt.Println("x = ", x, "and y = ", y, "and z = ", z) // 数据类型 // uint<8, 64>, int<16, 64>, float<32, 64>, complex<64, 128> // byte(uint8), uintptr, string // 变量声明周期:和C类似 // 局部:函数内部声明、函数参数 // 全局:函数外部声明 var p3 float64 = Pi * 3 // 指针(Go支持指针,这点不错) // 初看起来和C也差不多 // 支持指针,但无指针算术;自动垃圾回收(GC) var p *int32 = &y fmt.Println("address is", p, "value is", *p) p = nil // Go's nullptr // 分支 if p3 > 10 { fmt.Println("10 ~") } else { if p3 > 9 { fmt.Println("9 ~ 10") } else { fmt.Println("~ 9") } } // 基础使用和C类似,但是不需要手动break switch z { case 0: case 1, 2, 3: fallthrough // 强制执行后面的case case 100: default: } // select // 结构上和switch类似,但是需要对Go有更深的理解,不在基础语法部分详述了 // 数组 // 这里手动指定了数组大小 // 其实也可以交给编译器自动推断大小(如果有初始化的话) nums := [5]int32{127, 988, 1024} // var nums [5]int32 // 访问方式和C一样 // 以上是基础用法,更多语法糖在数组专题总结 // 循环 // 类C的写法(不太现代) // 可以只写循环条件,类似C的for(;condition;) for i := 0; i < 500; i++ { if i == 1 { continue } if i == 5 { break } // goto 也可以使用,这里没有举例 fmt.Print(i, i*i, ",") } fmt.Println() // 遍历一个数组,idx = [0, 5) for idx, value := range nums { fmt.Print(idx, value, ",") } fmt.Println() } // 定义结构体 type Person struct { name string id uint8 // 不能定义成员函数 } func sayHello(p *Person) { // 直接访问一个结构体 or 通过指针访问,都是使用"."操作符 fmt.Println("Hello, my name is", p.name, "my ID is", p.id) } // 小写字母开头:只在包的内部可见 // 参数列表可以省略前面的数据类型,写成这样:(x, y int32) // 「默认情况下,Go 语言使用的是值传递」 // 返回值类型写在后面,可以返回多个返回值 func some_func(x int32, y int32) (int32, bool) { // 初始化一个结构体的写法 var me Person = Person{name: "zh", id: 1} sayHello(&me) return x + y, true } // 大写字母开头:可以被包外部调用 // 常量、变量等符号,也是一样根据开头的字母大小写区分外部是否可见(这优雅吗?) func SomeFunc() bool { v, b := some_func(1, 2) return b && v == 3 } // 函数指针、闭包、方法等高级内容,这里没有介绍 // 「Go 语言没有传统面向对象语言中的类(class)和继承(inheritance)概念 // 而是通过组合(composition)和接口(interface)来实现类似的功能」 // 其他高级专题: // 切片(Slice)、范围(Range)、集合(Map)
开发框架:
go version go run . go run main.go go build / go build . # 构建当前目录的Package,依赖会被自动build (module root) go build ./... # 递归构建整个module go test / go test . # 测试当前Package,默认不会递归 (module root) go test ./... # 测试整个module # ./... 表示“从当前目录开始,递归地把所有子目录都包括进来” go mod init <url> go get <url> go mod tidy # 整理 go.mod 和 go.sum,保证它们和你的实际代码一致,修改 go.mod 后就执行一下
import ( "gorm.io/driver/sqlite" "gorm.io/gorm" )
Go很适合进行后端开发,可以直接用标准库开发,也可以选择使用框架来提高开发效率、简化结构管理,常用的后端框架(好像都是「单体服务」的框架?不是微服务的框架):
微服务(Microservices)是一种软件架构风格,它将大型应用程序拆分为一组小型、独立的服务模块。每个服务专注于实现特定的业务功能,运行在独立的进程中,并通过轻量级的通信机制(如 HTTP API)进行交互。这种架构使得各个服务可以由不同的团队独立开发、部署和维护,从而提高了系统的灵活性和可扩展性。
Go非常适合微服务:
| 优势 | 说明 |
| 编译成静态二进制 | 一行命令构建出无需依赖的可执行文件,易于部署 |
| 启动快、内存占用小 | 适合容器化、服务拆分 |
| 并发能力强 | goroutine 轻量,处理高并发天然优势 |
| 标准库支持好 | net/http + JSON + gRPC 支持开箱即用 |
| 良好的部署体验 | 配合Docker、K8s 极其顺畅 |
微服务模式有多个「节点」,节点之间是需要通信的
因为软件系统太复杂、太庞大,才需要使用微服务的模式,反而是比较简单的系统,一般会使用单体服务
可以作为Go的通信协议使用。都是Google开发的,一起用应该很方便吧…