Update
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# 01-basic-functions - 基础函数
|
||||
|
||||
## 知识点讲解
|
||||
|
||||
### 函数基本语法
|
||||
|
||||
```go
|
||||
func 函数名(参数列表) 返回值类型 {
|
||||
// 函数体
|
||||
}
|
||||
```
|
||||
|
||||
### 无参数无返回值
|
||||
|
||||
```go
|
||||
func greet() {
|
||||
fmt.Println("Hello, World!")
|
||||
}
|
||||
```
|
||||
|
||||
### 有参数无返回值
|
||||
|
||||
```go
|
||||
func greet(name string) {
|
||||
fmt.Printf("Hello, %s!\n", name)
|
||||
}
|
||||
```
|
||||
|
||||
### 单返回值
|
||||
|
||||
```go
|
||||
func add(a, b int) int {
|
||||
return a + b
|
||||
}
|
||||
```
|
||||
|
||||
### 多参数
|
||||
|
||||
```go
|
||||
func multiply(a, b, c int) int {
|
||||
return a * b * c
|
||||
}
|
||||
```
|
||||
|
||||
### 可变参数
|
||||
|
||||
```go
|
||||
func sum(nums ...int) int {
|
||||
total := 0
|
||||
for _, num := range nums {
|
||||
total += num
|
||||
}
|
||||
return total
|
||||
}
|
||||
```
|
||||
|
||||
**调用**:
|
||||
```go
|
||||
sum(1, 2, 3) // 直接传参
|
||||
nums := []int{1, 2, 3}
|
||||
sum(nums...) // 解包切片
|
||||
```
|
||||
|
||||
### 命名返回值
|
||||
|
||||
```go
|
||||
func divide(a, b int) (result int, err error) {
|
||||
if b == 0 {
|
||||
err = fmt.Errorf("division by zero")
|
||||
return
|
||||
}
|
||||
result = a / b
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
### 重要提示
|
||||
|
||||
- Go函数可以有多个返回值,这是Go的特色
|
||||
- 函数的参数和返回值都是按值传递(值传递)
|
||||
- 可变参数必须是函数的最后一个参数
|
||||
- 命名返回值可以让代码更清晰
|
||||
|
||||
## 学习目标
|
||||
|
||||
完成本练习后,你将:
|
||||
- ✅ 掌握函数的基本定义方式
|
||||
- ✅ 理解参数传递机制
|
||||
- ✅ 学会使用可变参数
|
||||
- ✅ 了解命名返回值的用法
|
||||
|
||||
## 练习说明
|
||||
|
||||
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
|
||||
@@ -0,0 +1,87 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func exercise1() int {
|
||||
fmt.Println("=== 练习1:无参数单返回值函数 ===")
|
||||
|
||||
// 定义一个函数square,接收一个int参数,返回其平方
|
||||
// 定义一个函数cube,接收一个int参数,返回其立方
|
||||
// 调用这两个函数并返回它们的和
|
||||
|
||||
____ func ____
|
||||
square := func(n int) ____ { return n * n }
|
||||
____
|
||||
}
|
||||
|
||||
cube := func(n int) ____ { ____ }
|
||||
|
||||
return ____(3) + ____(2)
|
||||
}
|
||||
|
||||
func exercise2(a, b int) {
|
||||
fmt.Println("\n=== 练习2:多个参数 ===")
|
||||
|
||||
// 定义一个函数,接收两个int参数a和b
|
||||
// 打印a + b, a - b, a * b
|
||||
// 格式: "加: 5, 减: 1, 乘: 6"
|
||||
fmt.Printf("加: %d, 减: %d, 乘: %d\n", ____, ____, ____)
|
||||
}
|
||||
|
||||
func exercise3(nums ...int) int {
|
||||
fmt.Println("\n=== 练习3:可变参数 ===")
|
||||
|
||||
// 定义一个可变参数函数,计算所有数字的和
|
||||
sum := ____
|
||||
for _, num := range ____ {
|
||||
____
|
||||
}
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise4(name, city string) (string, string) {
|
||||
fmt.Println("\n=== 练习4:命名返回值 ===")
|
||||
|
||||
// 使用命名返回值,返回两个字符串
|
||||
// nameWithGreeting: 格式为 "Hello, {name}"
|
||||
// info: 格式为 "{name} lives in {city}"
|
||||
|
||||
var ____ string
|
||||
var ____
|
||||
|
||||
nameWithGreeting = fmt.Sprintf("Hello, %s", name)
|
||||
info = fmt.Sprintf("%s lives in %s", name, city)
|
||||
|
||||
return ____, ____
|
||||
}
|
||||
|
||||
func exercise5(name string) string {
|
||||
fmt.Println("\n=== 练习5:匿名函数 ===")
|
||||
|
||||
// 使用匿名函数,对name进行处理
|
||||
// 返回大写的name
|
||||
// 提示:使用strings.ToUpper
|
||||
|
||||
____ := ____
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("=== 基础函数 练习 ===\n")
|
||||
|
||||
result1 := exercise1()
|
||||
fmt.Printf("练习1结果: %d\n", result1)
|
||||
|
||||
exercise2(3, 2)
|
||||
|
||||
result3 := exercise3(1, 2, 3, 4, 5)
|
||||
fmt.Printf("练习3结果: %d\n", result3)
|
||||
|
||||
s4, i4 := exercise4("张三", "北京")
|
||||
fmt.Printf("练习4结果: %s, %s\n", s4, i4)
|
||||
|
||||
result5 := exercise5("hello world")
|
||||
fmt.Printf("练习5结果: %s\n", result5)
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func captureOutput(f func()) string {
|
||||
old := os.Stdout
|
||||
r, w, _ := os.Pipe()
|
||||
os.Stdout = w
|
||||
|
||||
f()
|
||||
|
||||
w.Close()
|
||||
os.Stdout = old
|
||||
|
||||
var buf bytes.Buffer
|
||||
buf.ReadFrom(r)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func TestExercise1(t *testing.T) {
|
||||
result := exercise1()
|
||||
if result != 17 {
|
||||
t.Errorf("期望结果 17, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise2(t *testing.T) {
|
||||
output := captureOutput(func() { exercise2(3, 2) })
|
||||
if !strings.Contains(output, "加: 5, 减: 1, 乘: 6") {
|
||||
t.Error("期望输出 '加: 5, 减: 1, 乘: 6'")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise3(t *testing.T) {
|
||||
result := exercise3(1, 2, 3, 4, 5)
|
||||
if result != 15 {
|
||||
t.Errorf("期望结果 15, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise4(t *testing.T) {
|
||||
s4, i4 := exercise4("张三", "北京")
|
||||
if s4 != "Hello, 张三" {
|
||||
t.Errorf("期望 'Hello, 张三', 实际: %s", s4)
|
||||
}
|
||||
if i4 != "张三 lives in 北京" {
|
||||
t.Errorf("期望 '张三 lives in 北京', 实际: %s", i4)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise5(t *testing.T) {
|
||||
result := exercise5("hello world")
|
||||
if result != "HELLO WORLD" {
|
||||
t.Errorf("期望 'HELLO WORLD', 实际: %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMainFunction(t *testing.T) {
|
||||
output := captureOutput(main)
|
||||
|
||||
requiredSections := []string{
|
||||
"=== 基础函数 练习 ===",
|
||||
"练习1:无参数单返回值函数",
|
||||
"练习2:多个参数",
|
||||
"练习3:可变参数",
|
||||
"练习4:命名返回值",
|
||||
"练习5:匿名函数",
|
||||
}
|
||||
|
||||
for _, section := range requiredSections {
|
||||
if !strings.Contains(output, section) {
|
||||
t.Errorf("期望输出包含 '%s'", section)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
# 02-multiple-returns - 多返回值
|
||||
|
||||
## 知识点讲解
|
||||
|
||||
多返回值是Go语言的特色功能之一。
|
||||
|
||||
### 多返回值语法
|
||||
|
||||
```go
|
||||
func divide(a, b int) (int, error) {
|
||||
if b == 0 {
|
||||
return 0, fmt.Errorf("division by zero")
|
||||
}
|
||||
return a / b, nil
|
||||
}
|
||||
```
|
||||
|
||||
### 接收返回值
|
||||
|
||||
```go
|
||||
result, err := divide(10, 2)
|
||||
if err != nil {
|
||||
// 处理错误
|
||||
}
|
||||
```
|
||||
|
||||
### 忽略返回值
|
||||
|
||||
使用`_`忽略不需要的返回值:
|
||||
|
||||
```go
|
||||
result, _ := divide(10, 2) // 忽略错误
|
||||
_, err := divide(10, 0) // 只关心错误
|
||||
```
|
||||
|
||||
### 命名返回值
|
||||
|
||||
```go
|
||||
func rectangle(width, height int) (area, perimeter int) {
|
||||
area = width * height
|
||||
perimeter = 2 * (width + height)
|
||||
return // 此时return会返回所有命名返回值
|
||||
}
|
||||
```
|
||||
|
||||
## 学习目标
|
||||
|
||||
完成本练习后,你将:
|
||||
- ✅ 掌握多返回值的定义和使用
|
||||
- ✅ 学会忽略不需要的返回值
|
||||
- ✅ 理解命名的多返回值
|
||||
- ✅ 掌握错误处理的模式
|
||||
|
||||
## 练习说明
|
||||
|
||||
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
|
||||
@@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func exercise1(x, y int) (int, int) {
|
||||
// 返回x+y和x-y
|
||||
return ____, ____
|
||||
}
|
||||
|
||||
func exercise2(n int) (int, error) {
|
||||
// 如果n<0,返回0和错误
|
||||
// 否则返回n和nil
|
||||
if ____ {
|
||||
return ____, ____
|
||||
}
|
||||
return ____, ____
|
||||
}
|
||||
|
||||
func exercise3(s string) (bool, int) {
|
||||
// 返回字符串是否包含"hello"和字符串长度
|
||||
contains := true
|
||||
length := ____
|
||||
return ____, ____
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("=== 多返回值 练习 ===\n")
|
||||
|
||||
sum, diff := exercise1(10, 3)
|
||||
fmt.Printf("练习1: 加=%d, 减=%d\n", ____, ____)
|
||||
|
||||
result, err := exercise2(-5)
|
||||
if ____ {
|
||||
fmt.Printf("练习2: 错误 = %v\n", ____)
|
||||
} else {
|
||||
fmt.Printf("练习2: 结果 = %d\n", ____)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExercise1(t *testing.T) {
|
||||
sum, diff := exercise1(10, 3)
|
||||
if sum != 13 || diff != 7 {
|
||||
t.Errorf("期望 sum=13, diff=7, 实际 sum=%d, diff=%d", sum, diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise2(t *testing.T) {
|
||||
_, err := exercise2(-5)
|
||||
if err == nil {
|
||||
t.Error("期望返回错误,但返回了nil")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# 03-closures - 闭包
|
||||
|
||||
闭包是指能够访问其定义作用域外变量的函数。
|
||||
|
||||
## 知识点讲解
|
||||
|
||||
```go
|
||||
func makeAdder(x int) func(int) int {
|
||||
return func(y int) int {
|
||||
return x + y // 访问外部变量x
|
||||
}
|
||||
}
|
||||
|
||||
add5 := makeAdder(5)
|
||||
result := add5(3) // 返回8
|
||||
```
|
||||
|
||||
## 练习说明
|
||||
|
||||
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
|
||||
@@ -0,0 +1,7 @@
|
||||
# 04-higher-order - 高阶函数
|
||||
|
||||
函数作为参数和返回值。
|
||||
|
||||
## 练习说明
|
||||
|
||||
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
|
||||
@@ -0,0 +1,28 @@
|
||||
# Stage 03 - 函数
|
||||
|
||||
学习Go语言的函数特性,包括多返回值、闭包和高阶函数。
|
||||
|
||||
## 学习目标
|
||||
|
||||
完成本阶段后,你将掌握:
|
||||
- ✅ 函数定义与调用
|
||||
- ✅ 多返回值(Go的特色)
|
||||
- ✅ 闭包函数
|
||||
- ✅ 高阶函数(函数作为参数和返回值)
|
||||
|
||||
## 练习列表
|
||||
|
||||
1. **01-basic-functions** - 基础函数
|
||||
2. **02-multiple-returns** - 多返回值
|
||||
3. **03-closures** - 闭包
|
||||
4. **04-higher-order** - 高阶函数
|
||||
|
||||
## 预计用时
|
||||
|
||||
每练习15-20分钟,本阶段约1-1.5小时
|
||||
|
||||
## 备注
|
||||
|
||||
- 支持命名返回值
|
||||
- 支持可变参数
|
||||
- 函数是Go的一等公民
|
||||
Reference in New Issue
Block a user