从零开始学 Go:协程并发与 Web 开发初探
前言
最近开始系统学习 Go 语言,被它简洁的语法和强大的并发模型所吸引。本文是我学习过程中的一些笔记和代码整理,从最基础的语法到协程并发,再到用 Gin 搭建 Web 服务,希望能帮助同样在入门 Go 的同学快速上手。文章会由浅入深,配合可运行的代码示例,让你边看边练。
一、初识 Go:Hello World 与基础语法
1.1 第一个 Go 程序
Go 程序的入口是 main 包下的 main 函数,使用 fmt.Println 输出内容。
go
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
运行方式:
bash
go run main.go
1.2 变量声明
Go 是强类型语言,声明变量有两种常用方式:
go
// 显式声明类型
var name string = "你好"
// 短变量声明,类型自动推断(只能在函数内使用)
age := 18
注意:age := 18 推断为 int 类型,之后不能再赋值为字符串 age = "22",编译器会报错。
1.3 条件与循环
Go 的 if 语句不需要括号包裹条件,循环只有 for 一种关键字,但可以实现传统 while 的效果。
go
if age >= 18 {
fmt.Println("成年人")
}
// 经典 for 循环
for i := 0; i < 10; i++ {
fmt.Println(i)
}
1.4 数组、切片与映射
- 数组 :长度固定,如
[3]int{1,2,3} - 切片 :动态数组,使用更灵活,支持
append追加元素 - 映射:键值对集合
go
// 切片
slice := []int{1, 2, 3}
slice = append(slice, 4) // [1 2 3 4]
// map
m := map[string]int{"a": 1, "b": 2}
fmt.Println(m["a"]) // 输出: 1
1.5 函数与结构体
Go 没有类的概念,但可以通过结构体和方法实现面向对象风格。
go
// 普通函数
func add(a int, b int) int {
return a + b
}
// 结构体定义
type User struct {
Name string
Age int
}
// 创建实例
u := User{Name: "张三", Age: 18}
1.6 指针
Go 支持指针,常用于函数中修改外部变量。
go
func updateAge(age *int) {
*age = 20
}
x := 18
updateAge(&x)
fmt.Println(x) // 20
二、并发编程:goroutine 与 channel
2.1 什么是 goroutine?
Go 语言并发模型的核心是 goroutine,它是由 Go 运行时管理的轻量级线程。你可以把它理解为"协程",但比传统线程更轻量、开销更小,可以轻松创建成千上万个。
用一个厨房比喻来理解:
厨师一次只做一道菜,如果肉菜需要炖 20 分钟,他不用干等,而是利用这段时间去切土豆、准备其他食材------这就相当于 并发,多个任务交替推进,看起来像同时进行。
2.2 开启一个 goroutine
使用 go 关键字即可在后台启动一个新的 goroutine。
go
package main
import (
"fmt"
"time"
)
func sayHello() {
fmt.Println("hello world")
}
func main() {
go sayHello() // 新开协程执行
fmt.Println("main")
time.Sleep(time.Second) // 阻塞主线程,等待协程完成
}
注意 :如果主函数退出,所有 goroutine 都会被强制结束,所以这里用 time.Sleep 简单等待(实际开发中应使用同步机制)。
2.3 通道 channel:协程间通信
goroutine 之间可以通过 channel 安全地传递数据。channel 是类型相关的管道,你可以向它发送数据,也可以从它接收数据。
go
package main
import "fmt"
func main() {
ch := make(chan int) // 创建传递 int 的通道
go func() {
ch <- 100 // 发送数据到通道
}()
num := <-ch // 从通道接收数据,此处会阻塞等待
fmt.Println(num) // 100
}
发送和接收操作默认是阻塞的,这天然实现了 goroutine 之间的同步。
三、Web 开发:从 net/http 到 Gin 框架
3.1 标准库搭建 Web 服务器
Go 标准库 net/http 已经提供了基本的 HTTP 服务能力,无需第三方框架即可启动 Web 服务。
go
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello world")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
访问 http://localhost:8080 即可看到响应。
3.2 使用 Gin 框架
Gin 是 Go 生态中最流行的 Web 框架之一,类似于 Node.js 中的 Express,它以高性能和简洁的 API 著称,非常适合构建 RESTful 服务。
首先安装 Gin:
bash
go get -u github.com/gin-gonic/gin
然后编写一个简单的 JSON 接口:
go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello world",
})
})
r.Run(":8080")
}
gin.Default()创建默认路由器(自带 Logger 和 Recovery 中间件)r.GET注册路由和处理函数c.JSON返回 JSON 格式响应gin.H是map[string]interface{}的快捷写法
运行后访问 http://localhost:8080/hello,即可获得 JSON 数据。
3.3 项目依赖管理
你看到的 go.mod 文件是 Go Modules 的配置文件,记录了项目的模块名和依赖版本。当你在项目中导入 Gin 等第三方包时,go.mod 会自动更新依赖树,保证构建的可重现性。
go
module gin-demo
go 1.26.2
require (
github.com/gin-gonic/gin v1.12.0
// ... 其他间接依赖
)
四、总结与展望
通过以上内容,我们从零开始掌握了 Go 语言的:
- 基础语法:变量、循环、切片、结构体、指针
- 并发模型:goroutine 与 channel 的基本使用
- Web 开发:用标准库和 Gin 框架搭建 HTTP 服务
Go 语言的设计哲学是"少即是多",语法简单但功能强大,尤其在并发和网络编程领域表现突出。后续可以进一步学习:
- 错误处理与
defer - 接口
interface的妙用 - 更复杂的并发模式(select、sync 包)
- 数据库集成(如 MongoDB 驱动)
- 项目结构设计
如果你也对 Go 感兴趣,不妨跟着这些示例敲一遍代码,你会发现 Go 的简洁与高效确实让人着迷。