# 背景
- 2007年开始开发,2012年发布1.0版本;
# 编译环境
- 编译器,安装包的形式提供,windows大小为95M;
# 语法规则
Go 语言(Golang)由 Google 开发,以其简洁、高效和并发支持著称。以下是 Go 语言核心的语法规则概览,适合初学者快速掌握其基本结构和特点。
# 一、基础语法结构
# 1. 包(Package)
- 每个 Go 程序都由包组成。
main包是程序入口,必须包含main()函数。- 使用
import导入其他包。
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
package main声明这是一个可执行程序。import "fmt"引入格式化输入输出包。
# 2. 函数定义
func 函数名(参数列表) 返回类型 {
// 函数体
}
示例:
func add(a int, b int) int {
return a + b
}
// 多返回值(Go 特色)
func swap(a, b string) (string, string) {
return b, a
}
注意:Go 支持多返回值,常用于返回结果和错误。
# 3. 变量声明
- 使用
var声明变量:
var name string = "Alice"
var age int = 30
- 短变量声明(仅在函数内使用):
name := "Bob" // 自动推断类型
age := 25
- 声明多个变量:
var x, y int = 1, 2
a, b := "hello", 100
# 4. 常量(const)
const Pi = 3.14159
const (
StatusOK = 200
StatusNotFound = 404
)
# 二、数据类型
| 类型 | 示例 |
|---|---|
int | 整数(平台相关) |
int8/16/32/64 | 指定大小整数 |
uint | 无符号整数 |
float64 | 浮点数 |
bool | true, false |
string | "hello" |
rune | Unicode 字符(= int32) |
byte | 字节(= uint8) |
# 三、控制结构
# 1. if 语句
if x > 10 {
fmt.Println("大于10")
} else if x == 10 {
fmt.Println("等于10")
} else {
fmt.Println("小于10")
}
支持在
if前初始化变量:
if val := getValue(); val > 0 {
fmt.Println(val)
}
# 2. for 循环(Go 中唯一的循环结构)
// 标准 for
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// while 风格
for x < 10 {
x++
}
// 无限循环
for {
// 会一直执行,需 break 跳出
}
# 3. switch 语句
switch day {
case "Mon":
fmt.Println("星期一")
case "Tue":
fmt.Println("星期二")
default:
fmt.Println("其他")
}
Go 的
switch不需要break,自动防止穿透。
# 四、复合数据类型
# 1. 数组(Array)
固定长度:
var arr [3]int = [3]int{1, 2, 3}
# 2. 切片(Slice)(更常用)
动态数组:
s := []int{1, 2, 3}
s = append(s, 4)
# 3. 映射(Map)
键值对集合:
m := make(map[string]int)
m["age"] = 25
fmt.Println(m["age"])
// 或字面量
m := map[string]string{"name": "Tom"}
# 4. 结构体(struct)
自定义类型:
type Person struct {
Name string
Age int
}
p := Person{Name: "Alice", Age: 30}
fmt.Println(p.Name)
# 五、指针
Go 支持指针,但不支持指针运算。
var x int = 10
var p *int = &x // p 是指向 x 的指针
fmt.Println(*p) // 输出 10(解引用)
*p = 20 // 修改 x 的值
# 六、方法与接口
# 1. 方法(Method)
为类型定义行为:
type Rectangle struct {
Width, Height float64
}
// 方法:计算面积
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
r := Rectangle{3, 4}
fmt.Println(r.Area()) // 12
(r Rectangle)称为接收者,类似 OOP 中的 this。
# 2. 接口(Interface)
定义一组方法签名:
type Shape interface {
Area() float64
}
// Rectangle 实现了 Shape 接口(隐式实现)
Go 接口是隐式实现的,无需
implements关键字。
# 七、错误处理
Go 使用返回错误值的方式处理异常,而不是 try-catch。
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
err是error类型,约定函数最后一个返回值是error。
# 八、并发编程(Go 的亮点)
使用 goroutine 和 channel 实现并发。
# 1. Goroutine
轻量级线程,用 go 关键字启动:
go func() {
fmt.Println("并发执行")
}()
# 2. Channel
用于 goroutine 间通信:
ch := make(chan string)
go func() {
ch <- "hello"
}()
msg := <-ch
fmt.Println(msg) // 输出 hello
# 九、其他重要规则
| 特性 | 说明 |
|---|---|
| 大写标识符导出 | 首字母大写的变量/函数可被其他包访问(public),小写为私有(private) |
| := 只能在函数内使用 | var 可在全局或局部使用 |
| 没有分号 | 编译器自动插入,换行即结束 |
| 垃圾回收 | 自动内存管理 |
| defer | 延迟执行,常用于资源释放 |
defer fmt.Println("最后执行") // 函数结束前执行
fmt.Println("先执行")
# 模块化开发
Go 语言的包管理机制主要通过 Go Modules 实现,它从 Go 1.11 版本引入,并在 Go 1.16+ 成为默认和推荐的依赖管理方式。Go Modules 解决了早期 GOPATH 模式下的依赖版本混乱问题,支持语义化版本控制、依赖锁定和离线开发。
# 一、Go Modules 核心概念
- module:一个包含 Go 代码的根目录,其中有一个
go.mod文件。 - go.mod:声明模块路径、Go 版本和依赖项。
- go.sum:记录依赖模块的校验和,确保依赖完整性。
- 模块路径(module path):模块的唯一标识,通常是代码仓库地址(如
github.com/yourname/project)。
# 二、初始化一个新模块
在项目根目录下运行:
go mod init <模块路径>
示例:
go mod init github.com/yourname/myapp
执行后会生成 go.mod 文件:
module github.com/yourname/myapp
go 1.21
# 三、添加依赖
当你在代码中导入一个外部包并运行构建命令时,Go 会自动下载依赖并写入 go.mod。
# 方法 1:自动添加(推荐)
写代码时直接导入:
package main
import (
"fmt"
"github.com/gorilla/mux" // 第三方路由库
)
func main() {
r := mux.NewRouter()
fmt.Println("Server starting...")
}
然后运行:
go build
# 或
go run main.go
Go 会自动:
- 下载
github.com/gorilla/mux及其依赖 - 在
go.mod中添加require语句 - 生成
go.sum文件
生成的 go.mod 类似:
module github.com/yourname/myapp
go 1.21
require github.com/gorilla/mux v1.8.0
# 方法 2:手动添加依赖
go get github.com/gorilla/mux
你也可以指定版本:
go get github.com/gorilla/mux@v1.8.0
go get github.com/gorilla/mux@latest # 获取最新版
# 四、管理依赖版本
# 1. 升级依赖
go get github.com/gorilla/mux@v1.8.1
或升级到最新兼容版本:
go get -u github.com/gorilla/mux
-u会升级到次要版本或补丁版本(遵循语义化版本)。
# 2. 降级依赖
go get github.com/gorilla/mux@v1.7.0
# 3. 移除未使用的依赖
go mod tidy
这个命令会:
- 添加缺失的依赖
- 删除
go.mod中未使用的依赖 - 清理
go.sum
建议在每次修改代码后运行。
# 五、查看依赖信息
| 命令 | 说明 |
|---|---|
go list -m all | 列出当前模块及其所有依赖 |
go list -m -versions github.com/gorilla/mux | 查看某个包的所有可用版本 |
go mod graph | 显示依赖图(文本形式) |
go mod why package/path | 查看为何需要某个依赖 |
# 六、主模块与 replace / exclude
# 1. replace:替换依赖(如本地调试)
在 go.mod 中使用:
replace github.com/yourname/utils => ./local/utils
这会将远程包替换为本地目录,便于开发调试。
# 2. exclude:排除特定版本(不常用)
exclude github.com/some/pkg v1.2.3
# 七、发布自己的模块
设置模块路径为公开仓库地址(如 GitHub):
module github.com/yourname/mylib提交代码到 Git 仓库。
打标签发布版本:
git tag v1.0.0 git push origin v1.0.0
其他开发者即可通过:
import "github.com/yourname/mylib"
并使用 go get 引入你的模块。
# 八、常见问题与最佳实践
| 问题 | 解决方法 |
|---|---|
go: cannot find main module | 确保在 go.mod 所在目录运行命令 |
| 依赖下载慢 | 配置 GOPROXY(推荐): go env -w GOPROXY=https://goproxy.cn,direct(中国用户) |
| 想离线开发 | 使用 go build -mod=readonly 或 go mod download 预先下载 |
# 最佳实践:
- 项目根目录放
go.mod - 使用语义化版本(如
v1.2.3) - 定期运行
go mod tidy - 提交
go.mod和go.sum到版本控制(如 Git) - 不要提交
vendor目录(除非特殊要求),但可以生成:
go mod vendor # 将依赖复制到 vendor 目录