|
|
3 дней назад | |
|---|---|---|
| .. | ||
| README.md | 3 дней назад | |
| main.go | 3 дней назад | |
| main_test.go | 3 дней назад | |
第一课已经见过函数,这一课正式学习怎样拆分逻辑:参数传入数据、return 返回结果、多返回值表达是否有效,以及可变参数。
先手敲 main.go,运行成功后再阅读配套的 main_test.go。不要一开始就同时抄完测试代码。本课共享根目录的 go.mod,无需第三方依赖。
func add(a, b int) int {
return a + b
}
result := add(2, 3) // 这一行调用放在 main 等函数内部。
func:声明函数。add:函数名。a, b int:两个 int 参数,完整写法是 a int, b int。int:返回值类型。return:结束当前函数,并把结果交给调用方;不是结束整个程序。与 C 相比,Go 的类型写在名称后面,而且支持直接返回多个值。不需要为后面定义的普通函数先写函数原型,也不能直接在另一个函数内部声明具名函数;后续会学匿名函数。
函数定义的前后顺序不决定调用顺序:程序完成初始化后进入 main,按实际调用执行。普通函数不会因为写在文件里就自动运行。
func increase(value int) int {
value++
return value
}
调用 increase(count) 时,参数接收的是值的副本;修改内部整数 value,不会改变调用方的 count。想保留新值,可以用 count = increase(count)。
Go 的参数都是按值传递。但切片和 map 的值包含对底层数据的引用,复制参数值不等于复制全部数据:函数内修改切片元素或 map 条目,可能影响调用方。不能理解为“传进函数的任何数据都完全独立”。指针和更深入的共享行为后续单独学习。
func average(scores []int) (float64, bool) {
if len(scores) == 0 {
return 0, false
}
// 累加计算……
return 85, true // 此处仅示意返回形式,完整计算见 main.go。
}
调用时按顺序接收:
avg, ok := average(scores)
本课约定:ok 为 true 才表示平均值有效。空切片提前返回 false;真正的零分则返回 (0, true),避免混淆。
不需要某个返回值,可以使用 _,例如 _, ok = average(nil)。这里使用 =,因为 ok 已在同一作用域声明。
该函数只检查是否为空,不验证成绩是否位于 0~100,也暂不处理极大整数累加溢出。后续可在学习 error 后扩展输入校验。
func sum(values ...int) int {
total := 0
for _, value := range values {
total += value
}
return total
}
sum(1, 2, 3) 可以传多个整数,sum() 也合法。[]int 使用。sum(numbers...),将切片展开为参数。先掌握常规函数即可,本课暂不引入递归、闭包、泛型和 defer。
在仓库根目录执行:
New-Item -ItemType Directory -Force bin/07_functions | Out-Null
go build -o ./bin/07_functions/functions.exe ./lessons/07_functions
.\bin\07_functions\functions.exe
修改源码后需要重新编译。快速编译并运行:
go run ./lessons/07_functions
或者从根目录进入本课:
Set-Location lessons/07_functions
go run .
=== 无参数函数 ===
欢迎学习 Go 函数
=== 参数与返回值 ===
2 + 3 = 5
=== 值传递 ===
原变量:10,函数返回的新值:11
=== 多返回值与提前返回 ===
平均分:85.00
没有成绩,无法计算平均分
=== 可变参数 ===
直接传入多个整数:6
展开切片作为参数:60
不传参数:0
在仓库根目录执行:
go test -v ./lessons/07_functions
测试覆盖加法、整数值传递、正常平均值、小数平均值、零分、空切片和可变参数。这里的小数用例是可以精确表示的 80.5,因此直接比较;一般浮点计算测试可能需要容差判断。
count = increase(count) 更新调用方变量,比较前后区别。max(a, b int) int,返回较大的值。若另行手敲,放到本课的 practice/ 子目录,用 go run ./lessons/07_functions/practice 运行,不要在同一个包中重复声明 main 或其他同名函数。
下一课建议学习结构体,把姓名、年龄、成绩等不同类型的数据组合成一个对象。