Appearance
Go 语言基础
简介
Go(Golang)是 Google 开发的编译型静态语言,以简洁、高效、并发原生著称。
安装与配置
sh
# 下载安装 https://go.dev/dl/
# 验证
go version
# 环境变量
go env GOPATH # 模块缓存路径
go env GOROOT # Go 安装路径推荐使用 Go Modules(1.16+ 默认开启):
sh
go mod init project-name # 初始化模块
go mod tidy # 整理依赖
go mod download # 下载依赖基础语法
Hello World
go
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}变量与常量
go
// 变量声明
var name string = "Go"
var version = 1.21 // 类型推断
count := 42 // 短声明(函数内)
// 多变量
var x, y int = 1, 2
a, b := "hello", true
// 常量
const Pi = 3.14159
const (
StatusOK = 200
StatusNotFound = 404
)基本类型
go
bool // true / false
int, int8, int16, int32, int64
uint, uint8, uint16, uint32, uint64
uintptr
float32, float64
complex64, complex128
byte // uint8 别名
rune // int32 别名,表示 Unicode 码点
string // 字符串,不可变字符串
go
s := "Hello"
s[0] // 'H' (byte)
len(s) // 5
s + " Go" // "Hello Go"
strings.HasPrefix(s, "He") // true
strings.Split("a,b,c", ",") // ["a" "b" "c"]
strings.Join([]string{"a","b"}, "-") // "a-b"
strconv.Itoa(42) // "42"
strconv.Atoi("42") // 42, nil条件判断
go
if score >= 90 {
fmt.Println("A")
} else if score >= 60 {
fmt.Println("B")
} else {
fmt.Println("C")
}
// if 中声明临时变量
if err := doSomething(); err != nil {
fmt.Println(err)
}循环(仅 for)
go
// 三段式
for i := 0; i < 10; i++ {
fmt.Println(i)
}
// 类似 while
sum := 1
for sum < 100 {
sum += sum
}
// 无限循环
for {
break
}
// range 遍历
nums := []int{1, 2, 3}
for i, v := range nums {
fmt.Println(i, v)
}
for k, v := range map[string]int{"a": 1} {
fmt.Println(k, v)
}
for i, c := range "hello" {
fmt.Println(i, c) // i 是字节下标,c 是 rune
}Switch
go
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("macOS")
case "linux":
fmt.Println("Linux")
default:
fmt.Println(os)
}
// 无表达式 switch(替代 if-else 链)
score := 85
switch {
case score >= 90:
fmt.Println("A")
case score >= 60:
fmt.Println("B")
default:
fmt.Println("C")
}函数
go
// 基本定义
func add(a int, b int) int {
return a + b
}
// 参数类型简写
func add(a, b int) int
// 多返回值
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("除零")
}
return a / b, nil
}
// 具名返回值
func split(sum int) (x, y int) {
x = sum / 2
y = sum - x
return // 裸返回(不推荐长函数中使用)
}
// 可变参数
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
// 函数作为参数
func apply(f func(int) int, n int) int {
return f(n)
}
// 闭包
func counter() func() int {
i := 0
return func() int {
i++
return i
}
}defer
go
func readFile(path string) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close() // 函数返回前执行(后进先出)
// 处理文件...
return nil
}
// defer 栈
func example() {
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
// 输出: 3 2 1
}数组与切片
数组(固定长度)
go
var arr [3]int = [3]int{1, 2, 3}
arr2 := [...]int{4, 5, 6} // 自动推断长度
len(arr) // 3切片(动态长度)
go
// 创建
s1 := []int{1, 2, 3}
s2 := make([]int, 5) // len=5, cap=5
s3 := make([]int, 3, 5) // len=3, cap=5
// 追加
s1 = append(s1, 4, 5)
// 切片操作
arr := [...]int{0, 1, 2, 3, 4, 5}
s := arr[1:4] // [1 2 3]
s = arr[:3] // [0 1 2]
s = arr[3:] // [3 4 5]
s = arr[:] // [0 1 2 3 4 5]
// 复制
src := []int{1, 2, 3}
dst := make([]int, len(src))
copy(dst, src)
// 遍历
for i, v := range s {
fmt.Println(i, v)
}Map
go
// 创建
m := make(map[string]int)
m2 := map[string]int{"a": 1, "b": 2}
// 读写
m["key"] = 42
value := m["key"]
value, ok := m["key"] // ok 表示键是否存在
// 删除
delete(m, "key")
// 遍历
for k, v := range m {
fmt.Println(k, v)
}结构体与方法
go
type User struct {
ID int
Name string
Age int
}
// 创建实例
u1 := User{ID: 1, Name: "Alice", Age: 30}
u2 := User{ID: 2} // 其余字段零值
u3 := new(User) // 指针
// 方法(值接收者)
func (u User) Greet() string {
return "Hello, " + u.Name
}
// 方法(指针接收者,可修改)
func (u *User) SetName(name string) {
u.Name = name
}
// 使用
u := User{Name: "Bob"}
fmt.Println(u.Greet()) // Hello, Bob
u.SetName("Alice")接口
go
type Animal interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string { return "汪汪" }
type Cat struct{}
func (c Cat) Speak() string { return "喵喵" }
// 使用
func PrintSound(a Animal) {
fmt.Println(a.Speak())
}
// 空接口(Go 1.18+ 推荐用 any)
var v any = 42
v = "hello"
v = 3.14类型断言
go
var i any = "hello"
s, ok := i.(string) // ok=true, s="hello"
n, ok := i.(int) // ok=false
switch v := i.(type) {
case string:
fmt.Println("string:", v)
case int:
fmt.Println("int:", v)
default:
fmt.Println("unknown")
}错误处理
go
// 自定义错误
type MyError struct {
Code int
Message string
}
func (e *MyError) Error() string {
return fmt.Sprintf("error %d: %s", e.Code, e.Message)
}
// 使用
func doSomething() error {
return &MyError{Code: 400, Message: "bad request"}
}
// 错误判断
err := doSomething()
if err != nil {
var myErr *MyError
if errors.As(err, &myErr) {
fmt.Println(myErr.Code)
}
}
// 快速创建错误
errors.New("something went wrong")
fmt.Errorf("user %d not found", id)并发
Goroutine
go
go func() {
fmt.Println("并行执行")
}()
go doSomething() // 只要是函数就可以Channel
go
// 创建
ch := make(chan int)
ch := make(chan int, 10) // 缓冲通道
// 发送与接收
ch <- 42
value := <-ch
// 关闭
close(ch)
value, ok := <-ch // ok=false 表示通道已关闭
// range 遍历通道
for v := range ch {
fmt.Println(v)
}
// select(多路复用)
select {
case v := <-ch1:
fmt.Println(v)
case ch2 <- 42:
fmt.Println("发送成功")
case <-time.After(1 * time.Second):
fmt.Println("超时")
default:
fmt.Println("无就绪通道")
}示例:并发 worker
go
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
time.Sleep(time.Second)
results <- j * 2
}
}
func main() {
jobs := make(chan int, 10)
results := make(chan int, 10)
// 启动 3 个 worker
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// 发送任务
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// 收集结果
for r := 1; r <= 5; r++ {
<-results
}
}sync 包
go
var mu sync.Mutex
mu.Lock()
// 临界区
mu.Unlock()
// WaitGroup
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Println(id)
}(i)
}
wg.Wait() // 等待所有 goroutine 完成包管理
go
// 文件结构
myproject/
├── go.mod # 模块定义(module name, go 版本, 依赖)
├── main.go
└── utils/
└── helper.gogo
// main.go
package main
import "myproject/utils"
func main() {
utils.Hello()
}go
// utils/helper.go
package utils
import "fmt"
func Hello() {
fmt.Println("Hello from utils")
}go.mod 示例
module github.com/user/myproject
go 1.22
require (
github.com/gin-gonic/gin v1.9.1
)常用命令
sh
go build # 编译
go build -o app main.go # 输出文件名
go run main.go # 编译并运行
go test ./... # 运行所有测试
go test -v ./... # 详细输出
go test -bench=. # 性能测试
go fmt ./... # 格式化代码
go vet ./... # 静态检查
go mod tidy # 整理依赖
go mod graph # 查看依赖图
go env # 查看环境变量
go doc fmt.Println # 查看文档常用标准库
| 包 | 用途 |
|---|---|
fmt | 格式化 I/O |
net/http | HTTP 客户端/服务端 |
encoding/json | JSON 编解码 |
io / os | 文件与流操作 |
strings / strconv | 字符串处理 |
time | 时间操作 |
sync | 并发原语 |
context | 上下文控制(超时、取消) |
errors | 错误处理 |
database/sql | 数据库接口 |
flag | 命令行参数解析 |
testing | 测试框架 |
常用开发库
go
import (
"github.com/gin-gonic/gin" // Web 框架
"github.com/gorilla/mux" // HTTP 路由
"github.com/go-sql-driver/mysql" // MySQL 驱动
"github.com/lib/pq" // PostgreSQL 驱动
"github.com/redis/go-redis/v9" // Redis 客户端
"github.com/fsnotify/fsnotify" // 文件监控
"github.com/spf13/cobra" // CLI 框架
"github.com/spf13/viper" // 配置管理
"github.com/jmoiron/sqlx" // 数据库扩展
"github.com/golang-jwt/jwt/v5" // JWT
"github.com/stretchr/testify" // 测试断言
"go.uber.org/zap" // 日志
)