Go 语言入门教程——从 Hello World 到 Web 服务

Go 语言入门教程——从 Hello World 到 Web 服务

作者: CaoZH
日期: 2026-03-15
本文为原创教程


Go 语言(Golang)由 Google 开发,因其简洁的语法、原生并发支持和极快的编译速度,在云原生、微服务、CLI 工具等领域占据重要地位。Docker、Kubernetes、Prometheus 都是用 Go 写的。

一、安装 Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 下载安装包
wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz

# 配置环境变量
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
source ~/.bashrc

# macOS
brew install go

# 验证
go version

# 配置代理(国内)
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

二、基础语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package main

import "fmt"

func main() {
// 变量声明
var name string = "Go"
age := 28 // 简短声明

// 常量
const PI = 3.14159

// 基本类型
var isDone bool = false
var score int64 = 100
var price float64 = 99.9
var msg string = "Hello"

// 数组和切片
var arr [3]int = [3]int{1, 2, 3}
slice := []int{1, 2, 3}
slice = append(slice, 4)

// Map
user := map[string]string{
"name": "Alice",
"email": "alice@test.com",
}

// 结构体
type Person struct {
Name string
Age int
}
p := Person{Name: "Bob", Age: 30}

// 流程控制
if age >= 18 {
fmt.Println("成年")
} else {
fmt.Println("未成年")
}

for i := 0; i < 5; i++ {
fmt.Println(i)
}

for index, value := range slice {
fmt.Printf("%d: %d\n", index, value)
}

fmt.Printf("Hello %s!\n", name)
}

三、并发编程(Goroutine)

Go 最强大的特性——并发如此简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 启动一个 goroutine
go func() {
fmt.Println("在另一个线程中运行")
}()

// 使用 channel 通信
func main() {
ch := make(chan string)

go func() {
ch <- "Hello from goroutine"
}()

msg := <-ch
fmt.Println(msg)
}

// 带缓冲的 channel
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
fmt.Println(<-ch) // 1

// select 多路复用
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
case <-time.After(1 * time.Second):
fmt.Println("超时")
}

四、实战:Web 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// main.go
package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"sync"
"time"
)

// 用户模型
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}

// 内存数据库
type UserStore struct {
mu sync.RWMutex
users map[int]User
nextID int
}

func NewUserStore() *UserStore {
return &UserStore{
users: make(map[int]User),
nextID: 1,
}
}

func (s *UserStore) Create(name, email string) User {
s.mu.Lock()
defer s.mu.Unlock()

user := User{
ID: s.nextID,
Name: name,
Email: email,
CreatedAt: time.Now(),
}
s.users[user.ID] = user
s.nextID++
return user
}

func (s *UserStore) GetAll() []User {
s.mu.RLock()
defer s.mu.RUnlock()

result := make([]User, 0, len(s.users))
for _, u := range s.users {
result = append(result, u)
}
return result
}

// HTTP 处理器
type UserHandler struct {
store *UserStore
}

func (h *UserHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")

switch r.Method {
case http.MethodGet:
users := h.store.GetAll()
json.NewEncoder(w).Encode(users)

case http.MethodPost:
var req struct {
Name string `json:"name"`
Email string `json:"email"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, `{"error":"invalid request"}`, http.StatusBadRequest)
return
}

user := h.store.Create(req.Name, req.Email)
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)

default:
http.Error(w, `{"error":"method not allowed"}`, http.StatusMethodNotAllowed)
}
}

// 中间件
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %v", r.Method, r.URL.Path, time.Since(start))
})
}

func main() {
store := NewUserStore()
handler := &UserHandler{store: store}

// 添加路由
http.Handle("/api/users", loggingMiddleware(handler))

// 健康检查
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `{"status":"ok"}`)
})

addr := ":8080"
log.Printf("服务器启动在 %s", addr)
log.Fatal(http.ListenAndServe(addr, nil))
}
1
2
3
4
5
6
7
8
9
# 运行
go run main.go

# 测试
curl http://localhost:8080/health
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name":"Alice","email":"alice@test.com"}'
curl http://localhost:8080/api/users

五、包管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 初始化模块
go mod init myapp

# 添加依赖
go get github.com/gin-gonic/gin
go get github.com/go-sql-driver/mysql

# 更新依赖
go mod tidy

# 下载全部依赖
go mod download

# 编译
go build -o myapp main.go

六、总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## Go 的核心优势

✅ 简洁——没有复杂的泛型、继承、重载
✅ 并发——goroutine 和 channel 让并发编程简单
✅ 快速——编译速度极快,启动速度更快
✅ 跨平台——编译成单二进制,无需运行时
✅ 标准库——HTTP Server、JSON、加密都开箱即用

## 学习路径
1. ✅ 基础语法 + 类型系统
2. ✅ 接口与错误处理
3. ✅ goroutine 与 channel
4. ✅ HTTP 服务开发
5. ✅ 数据库操作
6. ✅ 测试(testing 包)

首发于 CaoZH 的笔记