下载工作台
Go 编程实战

流程控制与函数

试读上半部分 · 解锁后可读全文

第 3 章 · 流程控制与函数

本章目标:掌握 iffor(Go 无 while)、switchrange;编写多返回值函数与命名返回值;理解闭包基础与 defer 预告;在 toolkit-go 实现订单金额计算与慢日志分类;对照 java-dev ch03 控制流与 python-dev ch03 循环语法。

学时建议:3~4 小时(含 1.5 小时跟练)

前置:完成 go-dev ch02;建议已学 java-dev ch03python-dev ch03


3.1 场景说明:计算订单与过滤慢日志

toolkit-go~/learn-go/toolkit-go,模块 example.com/toolkit-go)在解析 access 日志时需要:

任务控制结构所在包
按耗时阈值标记慢请求if / switchinternal/filter
遍历日志行for + rangeinternal/logparser
汇总订单行金额函数 + 多返回值internal/calc
HTTP 状态码分类switchinternal/filter
toolkit-go/
├── internal/
│   ├── calc/
│   │   └── order.go          # CalcLinesTotal
│   ├── filter/
│   │   └── slow.go           # IsSlowRequest, ClassifyHTTP
│   └── model/
│       └── line.go           # LineItem
└── cmd/toolkit/main.go

3.2 if 语句与短变量声明

Go 的 if 可在条件前写简短语句,变量作用域限于 if-else 块。

// internal/filter/slow.go
package filter

const SlowThresholdMs = 500

func IsSlowRequest(durationMs int) bool {
	if durationMs <= 0 {
		return false
	}
	return durationMs >= SlowThresholdMs
}

func ClassifyDuration(ms int) string {
	switch {
	case ms < 100:
		return "fast"
	case ms < SlowThresholdMs:
		return "normal"
	default:
		return "slow"
	}
}
JavaGoPython
if (x > 0) { }if x > 0 { }if x > 0:
条件必须是 boolean条件必须是 boolean任意 truthy
无 if 内声明if err := fn(); err != nil { }无直接等价

if 短语句示例(error 处理预告 ch07)

if n := len(items); n == 0 {
	return fmt.Errorf("empty items")
} else if n > 100 {
	return fmt.Errorf("too many: %d", n)
}

3.3 for 循环:Go 唯一的循环关键字

Go 没有 while,所有循环用 for 表达。

package calc

import "fmt"

func DemoFor() {
	items := []int64{100, 200, 300}

	// 经典三段式 for
	for i := 0; i < len(items); i++ {
		_ = items[i]
	}

	// while 风格
	stock := 3
	for stock > 0 {
		stock--
	}

	// 无限循环(需 break / return)
	for {
		break
	}

	// range 遍历 slice
	for idx, price := range items {
		fmt.Println(idx, price)
	}

	// 只要值,忽略下标
	for _, price := range items {
		_ = price
	}
}
JavaGoPython
while (cond)for cond { }while cond:
for (int i=0; ...)for i := 0; i < n; i++for i in range(n)
for (Type x : arr)for _, x := range arrfor x in arr
do-while无(用 for + break)无原生

range 遍历 map(ch04 详讲 map)

cart := map[string]int{"go-book": 2, "go-mug": 1}
for slug, qty := range cart {
	_ = slug
	_ = qty
}

3.4 switch 语句

Go 的 switch 默认不贯穿(每个 case 自动 break),与 Java/C 不同。

// internal/filter/http_class.go
package filter

func ClassifyHTTP(status int) string {
	switch status {
	case 200, 201, 204:
		return "success"
	case 400, 401, 403, 404:
		return "client_error"
	case 500, 502, 503:
		return "server_error"
	default:
		return "unknown"
	}
}

func LogLevelLabel(level string) string {
	switch level {
	case "debug", "trace":
		return "LOW"
	case "info":
		return "INFO"
	case "warn", "error":
		return "HIGH"
	default:
		return "UNKNOWN"
	}
}
特性说明
无表达式 switchswitch { case x > 0: } 替代 if-else 链
多值 casecase 200, 201:
fallthrough显式贯穿到下一 case(慎用)
type switchany 做类型分支(ch06 接口)

type switch 预告

func describe(v any) string {
	switch x := v.(type) {
	case int:
		return fmt.Sprintf("int:%d", x)
	case string:
		return fmt.Sprintf("str:%s", x)
	default:
		return "other"
	}
}

3.5 函数声明与多返回值

Go 用 error 返回值 替代异常(详见 ch07),多返回值是惯用模式。

// internal/calc/order.go
package calc

import "fmt"

type LineItem struct {
	Slug     string
	Price    int64 // 分
	Quantity int
}

func Divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, fmt.Errorf("divide by zero")
	}
	return a / b, nil
}

func CalcOrderTotal(prices []int64) (total int64, err error) {
	if len(prices) == 0 {
		return 0, fmt.Errorf("empty order")
	}
	for _, p := range prices {
	 if p < 0 {
			return 0, fmt.Errorf("negative price: %d", p)
		}
		total += p
	}
	return total, nil
}

func CalcLinesTotal(lines []LineItem) (int64, error) {
	var total int64
	for _, ln := range lines {
		if ln.Quantity <= 0 {
			return 0, fmt.Errorf("invalid qty for %s", ln.Slug)
		}
		total += ln.Price * int64(ln.Quantity)
	}
	return total, nil
}
模式示例说明
双返回(T, error)最常见错误处理
多返回(v, ok, err)查 map / 解析
命名返回(total int64, err error)短函数可读;裸 return 返回命名值
无返回无括号仅副作用
JavaGo
try/catchif err != nil { return err }
单返回值多返回值
方法重载无重载;用不同函数名或可选参数模式

以下内容需解锁后阅读

试读已结束。解锁本章 ¥5.00,或开通年度会员畅读全部教程。
年度会员 ¥199.00/年; 小紫 AI 工作台有效会员 ¥99.00/年

正文仅在服务端鉴权后下发,未付费无法获取下半部分内容。