# 背景

  • 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()

errerror 类型,约定函数最后一个返回值是 error


# 八、并发编程(Go 的亮点)

使用 goroutinechannel 实现并发。

# 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 会自动:

  1. 下载 github.com/gorilla/mux 及其依赖
  2. go.mod 中添加 require 语句
  3. 生成 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

# 七、发布自己的模块

  1. 设置模块路径为公开仓库地址(如 GitHub):

    module github.com/yourname/mylib
    
  2. 提交代码到 Git 仓库。

  3. 打标签发布版本:

    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=readonlygo mod download 预先下载

# 最佳实践:

  • 项目根目录放 go.mod
  • 使用语义化版本(如 v1.2.3
  • 定期运行 go mod tidy
  • 提交 go.modgo.sum 到版本控制(如 Git)
  • 不要提交 vendor 目录(除非特殊要求),但可以生成:
go mod vendor  # 将依赖复制到 vendor 目录