Effective Go 学习笔记

Effective Go 学习笔记 本文档基于 Go 官方文档 Effective Go 整理编写。 每个知识点配有可运行的示例代码,帮助理解和实践。 注意:Effective Go 最初编写于 2009 年(Go 发布时),未涵盖泛型(Generics)等后续新增的语言特性。如需了解最新变化,请参考 Go Release Notes。 1. 引言(Introduction) Effective Go 是学习编写地道 Go 代码的指南。Go 是一种注重简洁、可靠、高效的语言。要写好 Go 代码,需要理解其特性和惯用法——不能简单地把 C++ 或 Java 的写法翻译成 Go。 核心理念:Go 程序应该在结构、命名、格式等方面遵循社区约定,这样其他 Go 程序员能轻松理解你的代码。 示例:Go 的"从问题出发"思维 package main import "fmt" // 传统 OOP 风格(不推荐) type Printer struct{} func (p Printer) Print(s string) { fmt.Println(s) } // Go 风格:用函数/接口组合(推荐) func Print(s string) { fmt.Println(s) } func main() { // Go 不推荐过度封装,简单的功能直接用函数 Print("Hello, Effective Go!") } 2. 格式(Formatting) Go 的格式由 gofmt(或 go fmt)自动处理。格式化问题交给机器,不再需要团队争论代码风格。 ...

August 4, 2026

Go by Example 完整学习笔记

Go by Example 完整学习笔记 以下内容整理自 Go by Example 网站的 18 个页面的代码、说明和输出。 Structs Go 的 structs(结构体) 是类型化的字段集合,用于将数据组合成记录。 package main import "fmt" // person 结构体包含 name 和 age 字段 type person struct { name string age int } // newPerson 用给定的名字构造一个新的 person 结构体 func newPerson(name string) *person { p := person{name: name} p.age = 42 return &p } func main() { // 按位置顺序创建结构体 fmt.Println(person{"Bob", 20}) // 按字段名初始化 fmt.Println(person{name: "Alice", age: 30}) // 省略的字段为零值 fmt.Println(person{name: "Fred"}) // & 前缀生成结构体指针 fmt.Println(&person{name: "Ann", age: 40}) // 使用构造函数 fmt.Println(newPerson("Jon")) // 用点号访问字段 s := person{name: "Sean", age: 50} fmt.Println(s.name) // 结构体指针自动解引用 sp := &s fmt.Println(sp.age) // 结构体是可变的 sp.age = 51 fmt.Println(sp.age) // 匿名结构体 dog := struct { name string isGood bool }{ "Rex", true, } fmt.Println(dog) } 运行输出: ...

August 4, 2026

Go 版本演进:从 1.0 到 1.26.5

Go 版本演进:从 1.0 到 1.26.5 的重大变化与特性 本文档梳理了 Go 语言从 2012 年 1.0 发布到 2026 年 1.26.5 的主要语言特性、标准库更新、工具链改进和性能提升,每个特性附简单代码示例。 参考来源: Go Release History Go 1.26 Release Notes Go 1.25 Release Notes Go features by version Go 1.0(2012-03-28) Go 的第一个稳定版本。核心特性: Go 1 兼容性承诺:后续版本保持向后兼容 标准库:net/http、encoding/json、template、crypto/tls 等 工具链:go get、go fmt、go test、go doc 并发模型:goroutine 和 channel package main import "fmt" func main() { // goroutine 与 channel ch := make(chan string) go func() { ch <- "Hello, Go 1.0!" }() fmt.Println(<-ch) } Go 1.1(2013-05-13) 竞态检测器(Race Detector) 运行时检测数据竞争,在测试或运行程序时通过 -race 标志启用。 ...

August 4, 2026

Go 标准库完全参考手册

Go 标准库完全参考手册 本文档基于 Go 1.26.5 标准库 整理编写。 涵盖所有公开标准库包的核心用法,每个功能配有代码示例和中文注释。 示例来源:Go 官方文档 pkg.go.dev fmt — 格式化输入输出 打印函数 fmt.Print — 默认格式输出 fmt.Printf — 格式化输出(占位符) fmt.Println — 输出后换行 fmt.Sprint / Sprintf / Sprintln — 返回字符串而非打印 fmt.Fprint / Fprintf / Fprintln — 写入 io.Writer 常用占位符 占位符 含义 示例输出 %v 值的默认格式 {7 -2.35} %+v 带字段名的结构体 {a:7 b:-2.35} %#v Go 语法表示 main.T{a:7, b:-2.35} %T 值的类型 main.T %d 十进制整数 42 %s 字符串 "hello" %q 带引号字符串 "hello" %f 浮点数 3.141593 %.2f 两位小数浮点数 3.14 %t 布尔值 true %x 十六进制 ff package main import "fmt" type Person struct { Name string Age int } func main() { // Printf — 格式化输出 fmt.Printf("Hello, %s!\n", "World") // %d — 整数占位符 fmt.Printf("年龄: %d 岁\n", 25) // %v — 任意值的默认格式,适合快速打印 fmt.Printf("值: %v\n", Person{"Alice", 30}) // %+v — 结构体带字段名,调试时非常有用 fmt.Printf("详细: %+v\n", Person{"Bob", 25}) // %#v — 完整的 Go 语法表示,用于调试复杂类型 fmt.Printf("Go语法: %#v\n", Person{"Charlie", 35}) // %T — 打印类型,调试接口值时很常用 var v interface{} = "hello" fmt.Printf("类型: %T\n", v) // %.2f — 控制浮点数精度 fmt.Printf("圆周率: %.2f\n", 3.14159265) // Sprintf — 返回格式化字符串而非打印 msg := fmt.Sprintf("结果: %d 条记录", 42) fmt.Println(msg) // Fprintf — 写入到 writer(如文件、HTTP 响应) // 下面的例子写入到标准错误 fmt.Fprintf(stderr, "错误: 文件未找到\n") } // 模拟 stderr,实际使用 os.Stderr var stderr = struct{ Write([]byte) (int, error) }{ Write: func(p []byte) (int, error) { return len(p), nil }, } 官方文档:https://pkg.go.dev/fmt@go1.26.5 ...

August 4, 2026

Go 大神技巧宝典(Go Guru Tips)

Go 大神技巧宝典(Go Guru Tips) 汇集 Go 社区高手的实用技巧、妙招、心得与代码片段,适合日常开发反复参考。 覆盖:并发、语言特性、性能、错误处理、测试、标准库、工程实践、工具链八大主题,共 100+ 条技巧 适用 Go 版本:1.21+(示例尽量覆盖 1.22 循环变量语义、1.23 range over func 等新特性) 代码规范:优先仅用标准库,gofmt 格式,遵循 Effective Go,中文注释 来源:Go 官方博客(go.dev/blog)、Go Wiki、Effective Go、Dave Cheney / Rob Pike 等社区大神的博客与演讲、Stack Overflow 高赞回答、go101.org、煎鱼 / 李文周等中文资源 前言 这份文档不是教程,而是一本「按图索骥」的速查手册:当你在写代码时卡住、或想确认某段代码是否地道时,翻开对应章节即可。每一条技巧都遵循统一格式——一句话说明、为什么有用、可直接编译的代码示例、踩坑注意事项与来源链接。 建议:先通读一遍总目录记住「哪里有」,需要时再「深挖」具体条目。 总目录 一、并发与 Goroutine 技巧(12 条) 二、语言特性实用技巧(14 条) 三、性能优化与内存管理(12 条) 四、错误处理与日志(12 条) 五、测试与代码质量(12 条) 六、标准库实战妙用(13 条) 七、工程实践与项目管理(13 条) 八、调试与工具链(15 条) 一、并发与 Goroutine 技巧(Concurrency & Goroutines) 一句话说明本主题:Go 并发编程的核心不是共享内存加锁,而是「通过通信共享内存」;本章收录 12 个高频、实用、可直接抄写的并发技巧,覆盖 channel 关闭原则、取消传播、扇出/扇入、工作池、errgroup、限流、防泄漏等日常工作最常遇到的场景。 技巧条目 1.1 Channel 关闭原则(Sender Closes) 一句话:channel 必须由发送方关闭,接收方绝不关闭,也绝不向已关闭的 channel 发送。 ...

August 4, 2026

Go 设计模式学习笔记(23 种 GoF 模式 × Go 惯用实现)

Go 设计模式学习笔记(23 种 GoF 模式 × Go 惯用实现) 本笔记基于 Refactoring Guru(中文站) 的经典 23 种 GoF 设计模式目录,用 Go 视角重新梳理。每个模式按「模式介绍 → 设计逻辑 → 应用场景 → 生产示例 → Go 简化 / 变体」展开,重点不是照搬经典类图,而是理解这些模式在 Go 中如何被简化、变体或替代,并学习 Go 社区基于语言特性(接口、组合、channel、函数一等公民)的惯用写法。所有代码均为可编译、可运行的独立示例,只用 Go 标准库,中文注释。 一、为什么 Go 需要重新审视设计模式 经典 GoF 模式诞生于 Java / C++ 时代,依赖继承、抽象类、protected、方法重载这些 OOP 机制。Go 刻意去掉了这些,换来的是更简单的语言: 经典 OOP 依赖 Go 的替代 继承(extends) 结构体嵌入 + 接口组合 抽象类 / 虚方法 接口(隐式实现)+ 函数字段 方法重载 函数式选项 / 变长参数 / 泛型 异常(exception) 返回值 error + 错误包装 观察者、事件 channel + goroutine 迭代器(Iterator) 原生 range + Go 1.23 range over func 因此同样一个模式,在 Go 里可能是原生支持(几乎不用写)、简化(一两行函数搞定)、变体(换一种更 Go 的形态),甚至反模式 / 低价值(社区明确不推荐)。本笔记的核心任务,就是给每个模式贴上这个「Go 形态」标签。 ...

August 4, 2026

Go 学习完整指南

Go 学习完整指南 本文档整合了 Go 官方学习资源 (go.dev/learn/) 和 Go by Example (gobyexample.com) 的全部内容,提供完整、可用、可重复学习的 Go 语言参考资料。 第一部分:Go 官方学习资源 1.1 Go 入门教程 (Getting Started) 来源:https://go.dev/doc/tutorial/getting-started 本教程快速介绍 Go 编程基础,包括安装 Go、编写 “Hello, World”、使用 go 命令运行代码、调用外部模块函数。 前提条件 有一定的编程经验 代码编辑器(VSCode、GoLand、Vim 等) 命令行终端 安装 Go 从 https://go.dev/dl 下载并安装最新版本(Go 1.26.5)。 编写第一个程序 # 创建工作目录 mkdir hello cd hello # 初始化模块 $ go mod init example/hello go: creating new go.mod: module example/hello hello.go — 第一个 Go 程序: package main import "fmt" func main() { fmt.Println("Hello, World!") } # 运行程序 $ go run . Hello, World! 调用外部包 使用 rsc.io/quote 包中的函数生成更有趣的输出: ...

August 4, 2026