Add Chapter 4: Functions and Interfaces - Closures, Defer, Panic/Recover, and Interfaces (Deep Dive)

This commit is contained in:
openclaw
2026-03-23 23:30:20 +00:00
parent 67e47dd5dd
commit aa46d006a8
3 changed files with 1327 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
module go-tutorial
go 1.21

429
chapters/chapter-4/main.go Normal file
View File

@@ -0,0 +1,429 @@
package main
import (
"fmt"
"os"
"time"
)
// 4.1 函数基础
func add(a, b int) int {
return a + b
}
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为零")
}
return a / b, nil
}
func divideNamed(a, b float64) (result float64, err error) {
if b == 0 {
err = fmt.Errorf("除数不能为零")
return
}
result = a / b
return
}
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
func functionBasics() {
fmt.Println("=== 函数基础 ===")
fmt.Println("add(3, 4):", add(3, 4))
result, err := divide(10, 2)
if err != nil {
fmt.Println("错误:", err)
} else {
fmt.Printf("10 / 2 = %.2f\n", result)
}
result2, _ := divideNamed(20, 4)
fmt.Printf("20 / 4 = %.2f\n", result2)
fmt.Println("sum(1,2,3,4,5):", sum(1, 2, 3, 4, 5))
nums := []int{10, 20, 30}
fmt.Println("sum(nums...):", sum(nums...))
}
// 4.2 闭包
func createCounter() func() int {
count := 0
return func() int {
count++
return count
}
}
func createMultiplier(factor int) func(int) int {
return func(x int) int {
return x * factor
}
}
func closureLoopBug() {
funcs := make([]func(), 3)
for i := 0; i < 3; i++ {
funcs[i] = func() {
fmt.Print(i, " ")
}
}
fmt.Print("Bug: ")
for _, f := range funcs {
f()
}
fmt.Println()
}
func closureLoopFix() {
funcs := make([]func(), 3)
for i := 0; i < 3; i++ {
i := i
funcs[i] = func() {
fmt.Print(i, " ")
}
}
fmt.Print("Fix: ")
for _, f := range funcs {
f()
}
fmt.Println()
}
func closureDemo() {
fmt.Println("\n=== 闭包示例 ===")
counter := createCounter()
fmt.Println("counter():", counter()) // 1
fmt.Println("counter():", counter()) // 2
fmt.Println("counter():", counter()) // 3
double := createMultiplier(2)
triple := createMultiplier(3)
fmt.Println("double(5):", double(5)) // 10
fmt.Println("triple(5):", triple(5)) // 15
closureLoopBug()
closureLoopFix()
}
// 4.3 defer
func deferDemo() {
fmt.Println("\n=== defer 示例 ===")
defer fmt.Println("延迟 1")
defer fmt.Println("延迟 2")
fmt.Println("立即执行")
// defer 参数求值
i := 0
defer fmt.Println("defer 时求值 i =", i)
i = 10
// 闭包 defer
defer func() {
fmt.Println("执行时求值 i =", i)
}()
fmt.Println("defer 结束")
}
func deferLoopDemo() {
fmt.Println("\n=== defer 循环陷阱 ===")
// 错误:循环中 defer
for i := 0; i < 3; i++ {
f, err := os.Create(fmt.Sprintf("temp%d.txt", i))
if err != nil {
fmt.Println("创建文件失败:", err)
continue
}
defer f.Close() // 所有 defer 在函数结束时执行
f.WriteString("test")
}
// 正确:立即执行
for i := 0; i < 3; i++ {
func() {
f, err := os.Create(fmt.Sprintf("temp2_%d.txt", i))
if err != nil {
return
}
defer f.Close()
f.WriteString("test")
}()
}
fmt.Println("文件操作完成")
}
// 4.4 panic 和 recover
func panicDemo() {
fmt.Println("\n=== panic 和 recover ===")
defer func() {
if r := recover(); r != nil {
fmt.Println("捕获 panic:", r)
}
}()
fmt.Println("开始")
panic("发生错误")
fmt.Println("不会执行")
}
type MyError struct {
Code int
Message string
}
func (e MyError) Error() string {
return fmt.Sprintf("错误码 %d: %s", e.Code, e.Message)
}
func safeDivide(a, b int) int {
if b == 0 {
panic(MyError{Code: 1001, Message: "除数不能为零"})
}
return a / b
}
func handlePanic() {
defer func() {
if r := recover(); r != nil {
if err, ok := r.(MyError); ok {
fmt.Printf("自定义错误:代码=%d, 消息=%s\n", err.Code, err.Message)
} else {
fmt.Printf("未知 panic: %v\n", r)
}
}
}()
safeDivide(10, 0)
}
func panicRecoverDemo() {
panicDemo()
handlePanic()
}
// 4.5 接口
type Speaker interface {
Speak() string
}
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return d.Name + " 汪汪叫"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return c.Name + " 喵喵叫"
}
func makeSound(s Speaker) {
fmt.Println(s.Speak())
}
func typeAssertionDemo() {
fmt.Println("\n=== 类型断言 ===")
var v interface{} = "hello"
// 基本断言
if s, ok := v.(string); ok {
fmt.Println("是字符串:", s)
}
// 类型开关
switch t := v.(type) {
case int:
fmt.Printf("整数:%d\n", t)
case string:
fmt.Printf("字符串:%s\n", t)
default:
fmt.Printf("未知类型:%T\n", t)
}
}
func interfaceDemo() {
dog := Dog{Name: "旺财"}
cat := Cat{Name: "咪咪"}
makeSound(dog)
makeSound(cat)
typeAssertionDemo()
}
// 4.6 综合案例:插件系统
type Plugin interface {
Name() string
Run() error
}
type HelloPlugin struct{}
func (h HelloPlugin) Name() string {
return "HelloPlugin"
}
func (h HelloPlugin) Run() error {
fmt.Println("Hello from plugin!")
return nil
}
type MathPlugin struct{}
func (m MathPlugin) Name() string {
return "MathPlugin"
}
func (m MathPlugin) Run() error {
fmt.Printf("2 + 2 = %d\n", 2+2)
return nil
}
func pluginDemo() {
fmt.Println("\n=== 插件系统 ===")
plugins := []Plugin{
HelloPlugin{},
MathPlugin{},
}
for _, p := range plugins {
fmt.Printf("加载插件:%s\n", p.Name())
if err := p.Run(); err != nil {
fmt.Println("插件运行失败:", err)
}
}
}
// 4.6 综合案例:中间件链
type Middleware func(Handler) Handler
type Handler func(string) string
func logging(next Handler) Handler {
return func(input string) string {
fmt.Printf("[LOG] 输入:%s\n", input)
result := next(input)
fmt.Printf("[LOG] 输出:%s\n", result)
return result
}
}
func timing(next Handler) Handler {
return func(input string) string {
start := time.Now()
result := next(input)
fmt.Printf("[TIME] 耗时:%v\n", time.Since(start))
return result
}
}
func auth(next Handler) Handler {
return func(input string) string {
if input == "" {
return "错误:空输入"
}
return next(input)
}
}
func businessLogic(input string) string {
return "处理结果:" + input
}
func middlewareDemo() {
fmt.Println("\n=== 中间件链 ===")
handler := auth(timing(logging(businessLogic)))
result := handler("测试数据")
fmt.Println("最终结果:", result)
}
// 4.6 综合案例:错误包装
type AppError struct {
Code int
Message string
Cause error
}
func (e *AppError) Error() string {
if e.Cause != nil {
return fmt.Sprintf("错误码 %d: %s (原因:%v)", e.Code, e.Message, e.Cause)
}
return fmt.Sprintf("错误码 %d: %s", e.Code, e.Message)
}
func wrapError(err error, code int, message string) error {
if err == nil {
return nil
}
return &AppError{
Code: code,
Message: message,
Cause: err,
}
}
func readFile(path string) ([]byte, error) {
return nil, fmt.Errorf("文件不存在")
}
func processFile(path string) error {
data, err := readFile(path)
if err != nil {
return wrapError(err, 1001, "读取文件失败")
}
if len(data) == 0 {
return wrapError(nil, 1002, "文件为空")
}
return nil
}
func errorHandlingDemo() {
fmt.Println("\n=== 错误处理链 ===")
err := processFile("test.txt")
if err != nil {
if appErr, ok := err.(*AppError); ok {
fmt.Printf("应用错误:代码=%d, 消息=%s\n", appErr.Code, appErr.Message)
if appErr.Cause != nil {
fmt.Printf("根本原因:%v\n", appErr.Cause)
}
} else {
fmt.Println("未知错误:", err)
}
}
}
func main() {
functionBasics()
closureDemo()
deferDemo()
deferLoopDemo()
panicRecoverDemo()
interfaceDemo()
pluginDemo()
middlewareDemo()
errorHandlingDemo()
}