外观
function
Phase 01 — Go Fundamentals · 知识点 11
1. 学习目标
- 定义和调用函数
- 使用多返回值(Go 特色)
- 理解命名返回值
- 传递 struct 值 vs 指针
2. 为什么需要
函数封装可复用逻辑:计算距离、校验电量、格式化设备状态。Go 函数支持多返回值,特别适合同时返回结果和 error(后续 Phase 02 深入)。
3. 核心概念
go
// 基本函数
func add(a, b int) int {
return a + b
}
// 多返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
// 命名返回值
func rectArea(w, h float64) (area float64) {
area = w * h
return // 裸 return,返回 area
}| 特性 | 说明 |
|---|---|
| 多返回值 | (result, error) 是标准模式 |
| 可变参数 | func sum(nums ...int) int |
| 函数是一等公民 | 可赋值给变量、作为参数 |
| 无默认参数 | 用 options struct 或函数式选项模式 |
4. 基础语法
go
package main
import (
"fmt"
"math"
)
type AGV struct {
ID string
X, Y float64
}
func distance(x1, y1, x2, y2 float64) float64 {
dx := x2 - x1
dy := y2 - y1
return math.Sqrt(dx*dx + dy*dy)
}
func isOverspeed(speed, maxSpeed float64) bool {
return speed > maxSpeed
}
func printAGV(a AGV) {
fmt.Printf("%s at (%.1f, %.1f)\n", a.ID, a.X, a.Y)
}
func main() {
agv := AGV{ID: "AGV-001", X: 10, Y: 5}
printAGV(agv)
fmt.Println("distance to origin:", distance(agv.X, agv.Y, 0, 0))
fmt.Println("overspeed:", isOverspeed(2.5, 2.0))
}5. 代码解析
- 同类型连续参数可写
(a, b int) - 多返回值必须全部接收或使用
_忽略 - 命名返回值在 defer 和短函数中有用,但过度使用降低可读性
6. JavaScript / TypeScript 对比
| Go | JS/TS |
|---|---|
| 多返回值 | 通常返回 object/array |
| 无默认参数 | 默认参数 / 解构 |
| error 作为返回值 | throw / try-catch |
| 函数 overload 靠不同签名 | TS 支持 overload |
7. 常见错误
- 忽略 error 返回值 → 至少
_或处理 - 大 struct 值传递 → 用
*AGV指针 - 可变参数传 nil slice →
fn(nums...)与fn(nil...)行为不同 - 命名返回值造成 shadowing → 谨慎使用
8. 实际应用
go
func parseAGVStatus(raw string) (AGV, error) {
// 解析逻辑...
}
func filterOverspeed(agvs []AGV, max float64) []AGV {
var result []AGV
for _, a := range agvs {
if a.Speed > max {
result = append(result, a)
}
}
return result
}9. 深入理解
闭包:函数可捕获外部变量。defer 将在 error-handling 文档详述。
10. 练习
- L1:基本函数与多返回值
- L2:distance / isOverspeed 函数
- L3:filter 函数处理 AGV slice
- L4:parse 函数返回 (result, error)
11. 学习检查
- [ ] Go 函数如何返回多个值?
- [ ] 何时传指针而非值?
- [ ]
_忽略返回值的作用?
12. 下一步
→ pointer:理解指针传递