Update
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# 01-pointers - 指针基础
|
||||
|
||||
## 知识点讲解
|
||||
|
||||
### 指针声明
|
||||
|
||||
```go
|
||||
var p *int // 声明一个int类型的指针
|
||||
x := 10
|
||||
p = &x // p是x的地址
|
||||
```
|
||||
|
||||
### 指针操作
|
||||
|
||||
```go
|
||||
x := 10
|
||||
p := &x // 取地址
|
||||
|
||||
fmt.Println(*p) // 解引用,输出10
|
||||
*p = 20 // 通过指针修改值
|
||||
fmt.Println(x) // 输出20
|
||||
```
|
||||
|
||||
### 指针与函数
|
||||
|
||||
```go
|
||||
function modifyValue(p *int) {
|
||||
*p = 100 // 修改指针指向的值
|
||||
}
|
||||
|
||||
x := 10
|
||||
modifyValue(&x) // 传递地址
|
||||
fmt.Println(x) // 输出100
|
||||
```
|
||||
|
||||
### 零值
|
||||
|
||||
```go
|
||||
var p *int // nil指针
|
||||
fmt.Println(p == nil) // true
|
||||
```
|
||||
|
||||
### 重要提示
|
||||
|
||||
- Go中有指针但没有指针运算
|
||||
- 指针可以用于共享数据、避免拷贝
|
||||
- 指针的零值是nil
|
||||
- 解引用nil指针会panic
|
||||
|
||||
## 学习目标
|
||||
|
||||
完成本练习后,你将:
|
||||
- ✅ 掌握指针的声明和创建
|
||||
- ✅ 学会取地址和解引用操作
|
||||
- ✅ 理解指针与函数参数的关系
|
||||
- ✅ 了解nil指针的概念
|
||||
|
||||
## 练习说明
|
||||
|
||||
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
|
||||
@@ -0,0 +1,96 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func exercise1() int {
|
||||
fmt.Println("=== 练习1:指针声明 ===")
|
||||
|
||||
// 声明一个int变量和一个指向它的指针
|
||||
var x int = 10
|
||||
var p ____ // 声明指针类型
|
||||
|
||||
p = ____ // p指向x的地址
|
||||
|
||||
fmt.Printf("x的值: %d, x的地址: %p\n", x, p)
|
||||
fmt.Printf("*p的值: %d\n", ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise2() int {
|
||||
fmt.Println("=== 练习2:指针解引用 ===")
|
||||
|
||||
// 通过指针修改值
|
||||
x := 20
|
||||
p := ____
|
||||
|
||||
____ = 30
|
||||
|
||||
fmt.Println("修改后x的值:", x)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func modifyByPointer(p *int) {
|
||||
// 通过指针修改值
|
||||
____ = 100
|
||||
}
|
||||
|
||||
func exercise3() int {
|
||||
fmt.Println("=== 练习3:指针作为函数参数 ===")
|
||||
|
||||
// 使用指针作为函数参数
|
||||
x := 50
|
||||
|
||||
____(&x)
|
||||
|
||||
if x != 100 {
|
||||
fmt.Println("指针参数修改失败!")
|
||||
}
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise4() bool {
|
||||
fmt.Println("=== 练习4:指针零值 ===")
|
||||
|
||||
// 检查指针的零值
|
||||
var p ____
|
||||
|
||||
fmt.Printf("未初始化的指针: %v, 是否为nil: %t\n", p, ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise5() int {
|
||||
fmt.Println("=== 练习5:指针与数组 ===")
|
||||
|
||||
// 使用指针访问数组元素
|
||||
arr := [5]int{10, 20, 30, 40, 50}
|
||||
|
||||
p := ____
|
||||
|
||||
fmt.Printf("第一个元素: %d\n", ____)
|
||||
fmt.Printf("第二个元素: %d\n", ____(p+1))
|
||||
|
||||
return arr[0]
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("=== 指针 练习 ===\n")
|
||||
|
||||
result1 := exercise1()
|
||||
fmt.Printf("练习1结果: %d\n", result1)
|
||||
|
||||
result2 := exercise2()
|
||||
fmt.Printf("练习2结果: %d\n", result2)
|
||||
|
||||
result3 := exercise3()
|
||||
fmt.Printf("练习3结果: %d\n", result3)
|
||||
|
||||
result4 := exercise4()
|
||||
fmt.Printf("练习4结果: %t\n", result4)
|
||||
|
||||
result5 := exercise5()
|
||||
fmt.Printf("练习5结果: %d\n", result5)
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
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 != 10 {
|
||||
t.Errorf("期望 10, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise2(t *testing.T) {
|
||||
result := exercise2()
|
||||
if result != 30 {
|
||||
t.Errorf("期望 30, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise3(t *testing.T) {
|
||||
result := exercise3()
|
||||
if result != 100 {
|
||||
t.Errorf("期望 100, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise4(t *testing.T) {
|
||||
result := exercise4()
|
||||
if !result {
|
||||
t.Errorf("期望 true, 实际: %t", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise5(t *testing.T) {
|
||||
result := exercise5()
|
||||
if result != 10 {
|
||||
t.Errorf("期望 10, 实际: %d", 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,63 @@
|
||||
# 02-new-make - new vs make
|
||||
|
||||
## 知识点讲解
|
||||
|
||||
### new函数
|
||||
|
||||
```go
|
||||
p := new(int) // 返回指向int类型零值的指针
|
||||
fmt.Println(*p) // 输出: 0
|
||||
*p = 10 // 可以通过指针修改值
|
||||
```
|
||||
|
||||
**特点**:
|
||||
- 返回指向类型的零值指针
|
||||
- 适用于所有类型
|
||||
- 内存已初始化为零值但不执行构造逻辑
|
||||
|
||||
### make函数
|
||||
|
||||
```go
|
||||
// 创建切片
|
||||
s := make([]int, 5) // [0, 0, 0, 0, 0]
|
||||
s := make([]int, 3, 10) // 长度3, 容量10
|
||||
|
||||
// 创建map
|
||||
m := make(map[string]int)
|
||||
m["key"] = 100
|
||||
|
||||
// 创建channel
|
||||
ch := make(chan int)
|
||||
```
|
||||
|
||||
**特点**:
|
||||
- 只用于创建引用类型(slice、map、channel)
|
||||
- 返回的是初始化后的类型(非指针)
|
||||
- 会执行类型的初始化逻辑
|
||||
|
||||
### 主要区别
|
||||
|
||||
| 特性 | new() | make() |
|
||||
|------|-------|--------|
|
||||
| 返回类型 | 指针 | 值 |
|
||||
| 适用类型 | 所有类型 | slice, map, channel |
|
||||
| 初始化 | 仅零值 | 完整初始化 |
|
||||
| 常用场景 | 需要指针时 | 创建引用类型时 |
|
||||
|
||||
### 重要提示
|
||||
|
||||
- 使用 `new` 创建的指针指向零值
|
||||
- 使用 `make` 创建的引用类型可以直接使用
|
||||
- 不要用 `new` 创建切片、map或channel
|
||||
|
||||
## 学习目标
|
||||
|
||||
完成本练习后,你将:
|
||||
- ✅ 理解new和make的区别
|
||||
- ✅ 掌握new的使用场景
|
||||
- ✅ 掌握make的使用场景
|
||||
- ✅ 学会正确选择new或make
|
||||
|
||||
## 练习说明
|
||||
|
||||
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
|
||||
@@ -0,0 +1,102 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func exercise1() int {
|
||||
fmt.Println("=== 练习1:new创建指针 ===")
|
||||
|
||||
// 使用new创建一个int类型的指针
|
||||
p := ____ // new返回指向int零值的指针
|
||||
|
||||
fmt.Printf("new创建的指针: %v, 解引用值: %d\n", p, ____)
|
||||
|
||||
*p = 10
|
||||
|
||||
fmt.Printf("修改后的值: %d\n", ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise2() []int {
|
||||
fmt.Println("=== 练习2:make创建切片 ===")
|
||||
|
||||
// 使用make创建一个长度为5的int切片
|
||||
s := ____
|
||||
|
||||
fmt.Printf("创建的切片: %v, 长度: %d\n", s, ____)
|
||||
|
||||
fmt.Printf("切片的第一个元素: %d\n", s[____])
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise3() map[string]int {
|
||||
fmt.Println("=== 练习3:make创建map ===")
|
||||
|
||||
// 使用make创建一个map
|
||||
m := ____
|
||||
|
||||
m["张三"] = 90
|
||||
|
||||
fmt.Printf("map内容: %v\n", ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise4() int {
|
||||
fmt.Println("=== 练习4:new vs make - 切片 ===")
|
||||
|
||||
// 分别使用new和make创建切片,观察区别
|
||||
newSlice := new([]int) // 返回指针,指向nil切片
|
||||
makeSlice := make([]int, 3) // 返回切片实例
|
||||
|
||||
fmt.Printf("new创建的切片: %v, 是否为nil: %t\n", ____, *newSlice == nil)
|
||||
fmt.Printf("make创建的切片: %v, 是否为nil: %t\n", ____, makeSlice == nil)
|
||||
|
||||
if *newSlice == nil {
|
||||
*newSlice = make([]int, 3)
|
||||
____[0] = 100
|
||||
}
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise5() string {
|
||||
fmt.Println("=== 练习5:new vs make - 结构体 ===")
|
||||
|
||||
// 使用new创建结构体指针
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
p := ____
|
||||
|
||||
fmt.Printf("new创建的结构体: %+v\n", ____)
|
||||
|
||||
p.Name = "张三"
|
||||
p.Age = 20
|
||||
|
||||
fmt.Printf("修改后的结构体: %+v\n", ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("=== new vs make 练习 ===\n")
|
||||
|
||||
result1 := exercise1()
|
||||
fmt.Printf("练习1结果: %d\n", result1)
|
||||
|
||||
result2 := exercise2()
|
||||
fmt.Printf("练习2结果: %v\n", result2)
|
||||
|
||||
result3 := exercise3()
|
||||
fmt.Printf("练习3结果: %v\n", result3)
|
||||
|
||||
result4 := exercise4()
|
||||
fmt.Printf("练习4结果: %d\n", result4)
|
||||
|
||||
result5 := exercise5()
|
||||
fmt.Printf("练习5结果: %s\n", result5)
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
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 != 10 {
|
||||
t.Errorf("期望 10, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise2(t *testing.T) {
|
||||
result := exercise2()
|
||||
if len(result) != 5 {
|
||||
t.Errorf("期望长度 5, 实际: %d", len(result))
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise3(t *testing.T) {
|
||||
result := exercise3()
|
||||
if len(result) != 1 {
|
||||
t.Errorf("期望长度 1, 实际: %d", len(result))
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise4(t *testing.T) {
|
||||
result := exercise4()
|
||||
if result != 100 {
|
||||
t.Errorf("期望 100, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise5(t *testing.T) {
|
||||
result := exercise5()
|
||||
if result != "张三" {
|
||||
t.Errorf("期望 '张三', 实际: %s", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMainFunction(t *testing.T) {
|
||||
output := captureOutput(main)
|
||||
|
||||
requiredSections := []string{
|
||||
"=== new vs make 练习 ===",
|
||||
"练习1:new创建指针",
|
||||
"练习2:make创建切片",
|
||||
"练习3:make创建map",
|
||||
"练习4:new vs make - 切片",
|
||||
"练习5:new vs make - 结构体",
|
||||
}
|
||||
|
||||
for _, section := range requiredSections {
|
||||
if !strings.Contains(output, section) {
|
||||
t.Errorf("期望输出包含 '%s'", section)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
# 03-value-pointer - 值传递vs指针传递
|
||||
|
||||
## 知识点讲解
|
||||
|
||||
### 值传递
|
||||
|
||||
```go
|
||||
func modifyValue(x int) {
|
||||
x = 100 // 修改的是函数内的副本
|
||||
}
|
||||
|
||||
num := 10
|
||||
modifyValue(num)
|
||||
fmt.Println(num) // 输出: 10(原值不变)
|
||||
```
|
||||
|
||||
### 指针传递
|
||||
|
||||
```go
|
||||
func modifyPointer(p *int) {
|
||||
*p = 100 // 修改的是指针指向的值
|
||||
}
|
||||
|
||||
num := 10
|
||||
modifyPointer(&num)
|
||||
fmt.Println(num) // 输出: 100(原值被修改)
|
||||
```
|
||||
|
||||
### 结构体的值传递
|
||||
|
||||
```go
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
func modifyPersonValue(p Person) {
|
||||
p.Name = "李四" // 修改副本
|
||||
}
|
||||
|
||||
p := Person{Name: "张三", Age: 20}
|
||||
modifyPersonValue(p)
|
||||
fmt.Println(p.Name) // 输出: 张三(原值不变)
|
||||
```
|
||||
|
||||
### 结构体的指针传递
|
||||
|
||||
```go
|
||||
func modifyPersonPointer(p *Person) {
|
||||
p.Name = "李四" // 修改原值
|
||||
}
|
||||
|
||||
p := Person{Name: "张三", Age: 20}
|
||||
modifyPersonPointer(&p)
|
||||
fmt.Println(p.Name) // 输出: 李四(原值被修改)
|
||||
```
|
||||
|
||||
### 重要提示
|
||||
|
||||
- Go中所有参数传递都是值传递
|
||||
- 传递指针实际是拷贝指针地址,但通过指针可以修改原值
|
||||
- 大结构体使用指针传递可以避免大量拷贝
|
||||
- 切片、map等引用类型传递也具有类似指针的行为
|
||||
|
||||
## 学习目标
|
||||
|
||||
完成本练习后,你将:
|
||||
- ✅ 理解值传递和指针传递的区别
|
||||
- ✅ 掌握何时使用值传递
|
||||
- ✅ 掌握何时使用指针传递
|
||||
- ✅ 了解性能方面的考虑
|
||||
|
||||
## 练习说明
|
||||
|
||||
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
|
||||
@@ -0,0 +1,130 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func modifyByValue(x int) int {
|
||||
// 值传递:修改函数内的副本
|
||||
x = ____
|
||||
return ____
|
||||
}
|
||||
|
||||
func modifyByPointer(p *int) int {
|
||||
// 指针传递:修改指针指向的值
|
||||
____ = ____
|
||||
return ____
|
||||
}
|
||||
|
||||
type Counter struct {
|
||||
Value int
|
||||
}
|
||||
|
||||
func (c Counter) Increment() int {
|
||||
// 值接收者:修改副本
|
||||
c.Value += 1
|
||||
return ____
|
||||
}
|
||||
|
||||
func (c *Counter) IncrementPointer() int {
|
||||
// 指针接收者:修改原值
|
||||
c.Value += ____
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise1() int {
|
||||
fmt.Println("=== 练习1:值传递 ===")
|
||||
|
||||
// 值传递不会修改原值
|
||||
num := 10
|
||||
|
||||
result := modifyByValue(____)
|
||||
|
||||
fmt.Printf("原值: %d, 函数返回值: %d\n", ____, result)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise2() int {
|
||||
fmt.Println("=== 练习2:指针传递 ===")
|
||||
|
||||
// 指针传递会修改原值
|
||||
num := 10
|
||||
|
||||
result := ____
|
||||
|
||||
fmt.Printf("原值: %d, 函数返回值: %d\n", ____, result)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise3() int {
|
||||
fmt.Println("=== 练习3:结构体值传递 ===")
|
||||
|
||||
// 值方法不会修改原结构体
|
||||
counter := Counter{Value: 0}
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
counter.____()
|
||||
}
|
||||
|
||||
fmt.Printf("原结构体值: %d\n", ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func exercise4() int {
|
||||
fmt.Println("=== 练习4:结构体指针传递 ===")
|
||||
|
||||
// 指针方法会修改原结构体
|
||||
counter := Counter{Value: 0}
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
counter.____()
|
||||
}
|
||||
|
||||
fmt.Printf("原结构体值: %d\n", ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
type SliceContainer struct {
|
||||
Data []int
|
||||
}
|
||||
|
||||
func (s *SliceContainer) Add(value int) {
|
||||
// 指针方法可以修改切片内容
|
||||
s.Data = append(____, ____)
|
||||
}
|
||||
|
||||
func exercise5() []int {
|
||||
fmt.Println("=== 练习5:切片与结构体 ===")
|
||||
|
||||
// 使用切片的结构体
|
||||
container := SliceContainer{Data: []int{}}
|
||||
|
||||
container.Add(10)
|
||||
container.Add(20)
|
||||
container.Add(30)
|
||||
|
||||
fmt.Printf("切片内容: %v\n", ____)
|
||||
|
||||
return ____
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("=== 值传递 vs 指针传递 练习 ===\n")
|
||||
|
||||
result1 := exercise1()
|
||||
fmt.Printf("练习1结果: %d\n", result1)
|
||||
|
||||
result2 := exercise2()
|
||||
fmt.Printf("练习2结果: %d\n", result2)
|
||||
|
||||
result3 := exercise3()
|
||||
fmt.Printf("练习3结果: %d\n", result3)
|
||||
|
||||
result4 := exercise4()
|
||||
fmt.Printf("练习4结果: %d\n", result4)
|
||||
|
||||
result5 := exercise5()
|
||||
fmt.Printf("练习5结果: %v\n", result5)
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
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 != 10 {
|
||||
t.Errorf("期望 10, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise2(t *testing.T) {
|
||||
result := exercise2()
|
||||
if result != 100 {
|
||||
t.Errorf("期望 100, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise3(t *testing.T) {
|
||||
result := exercise3()
|
||||
if result != 0 {
|
||||
t.Errorf("期望 0, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise4(t *testing.T) {
|
||||
result := exercise4()
|
||||
if result != 5 {
|
||||
t.Errorf("期望 5, 实际: %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExercise5(t *testing.T) {
|
||||
result := exercise5()
|
||||
expected := []int{10, 20, 30}
|
||||
if len(result) != len(expected) {
|
||||
t.Errorf("期望长度 %d, 实际: %d", len(expected), len(result))
|
||||
}
|
||||
for i, val := range expected {
|
||||
if result[i] != val {
|
||||
t.Errorf("索引 %d 期望 %d, 实际: %d", i, val, result[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMainFunction(t *testing.T) {
|
||||
output := captureOutput(main)
|
||||
|
||||
requiredSections := []string{
|
||||
"=== 值传递 vs 指针传递 练习 ===",
|
||||
"练习1:值传递",
|
||||
"练习2:指针传递",
|
||||
"练习3:结构体值传递",
|
||||
"练习4:结构体指针传递",
|
||||
"练习5:切片与结构体",
|
||||
}
|
||||
|
||||
for _, section := range requiredSections {
|
||||
if !strings.Contains(output, section) {
|
||||
t.Errorf("期望输出包含 '%s'", section)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user