This commit is contained in:
2026-03-13 23:54:07 +08:00
parent 9c065bcae4
commit d0f8c44411
45 changed files with 3439 additions and 1 deletions
+65
View File
@@ -0,0 +1,65 @@
# 01-variables - 变量声明与作用域
## 知识点讲解
### 变量声明方式
Go语言有多种变量声明方式:
1. **标准声明**:`var 变量名 类型`
```go
var name string
var age int
```
2. **声明并初始化**:`var 变量名 类型 = 值` 或 `var 变量名 = 值`(类型推断)
```go
var name string = "Alice"
var age = 25 // 类型自动推断为int
```
3. **短变量声明**:`变量名 := 值`(只能在函数内使用)
```go
name := "Alice"
age := 25
```
4. **批量声明**:
```go
var (
name string
age int
score float64
)
```
5. **多变量声明**:
```go
var x, y int = 1, 2
a, b := 3, 4
```
### 变量作用域
- **全局变量**:在函数外声明,包内可见
- **局部变量**:在函数内声明,仅函数内可见
- **代码块变量**:在if、for等代码块内声明,仅代码块内可见
### 重要提示
- 变量声明后必须使用,否则会编译错误
- `:=` 只能在函数内使用
- 同一作用域内不能重复声明同名变量
- 未初始化的变量会有零值:int=0, string="", float=0.0, bool=false, pointer=nil
## 学习目标
完成本练习后,你将:
- ✅ 掌握5种变量声明方式
- ✅ 理解变量作用域规则
- ✅ 了解变量的零值
- ✅ 能够正确使用短变量声明
## 练习说明
打开 `main.go`,根据注释提示填充代码,完成后运行 `go test -v` 验证答案。
+101
View File
@@ -0,0 +1,101 @@
package main
import "fmt"
var globalVar int = 100
func main() {
exercise1()
exercise2()
exercise3()
exercise4()
exercise5()
}
// 练习1:标准变量声明
// 目标:使用var关键字声明不同类型的变量并初始化
func exercise1() {
fmt.Println("=== 练习1:标准变量声明 ===")
// 声明一个string类型变量,命名为name,值为"张三"
var name string = "张三"
// 声明一个int类型变量,命名为age,值为25
var age int = 25
// 使用类型推断声明一个bool类型变量,命名为isStudent,值为true
var isStudent bool = true
fmt.Printf("姓名: %s, 年龄: %d, 是学生: %t\n", name, age, isStudent)
}
// 练习2:短变量声明
// 目标:使用:=进行变量声明(只能在函数内使用)
func exercise2() {
fmt.Println("\n=== 练习2:短变量声明 ===")
// 使用:=声明一个string变量,命名为city,值为"北京"
city := "北京"
// 使用:=声明一个float64变量,命名为price,值为99.5
price := 99.5
// 使用:=声明多个变量,x=10, y=20, z=30
x, y, z := ____
fmt.Printf("城市: %s, 价格: %.2f, 坐标: (%d, %d, %d)\n", city, price, x, y, z)
}
// 练习3:批量声明
// 目标:使用var()批量声明多个变量
func exercise3() {
fmt.Println("\n=== 练习3:批量声明 ===")
// 使用var()批量声明以下变量:
// username: string = "go_learner"
// email: string = "learner@example.com"
// level: int = 1
// experience: float64 = 0.0
var (
username ____
email ____
level ____
experience ____
)
fmt.Printf("用户: %s\n邮箱: %s\n等级: %d\n经验值: %.1f\n",
username, email, level, experience)
}
// 练习4:变量作用域
// 目标:理解全局变量和局部变量的作用域
func exercise4() {
fmt.Println("\n=== 练习4:变量作用域 ===")
// 直接打印全局变量globalVar的值
fmt.Printf("全局变量 globalVar 的值: %d\n", ____)
// 声明一个局部变量,命名为localVar,值为50
localVar := ____
fmt.Printf("局部变量 localVar 的值: %d\n", localVar)
}
// 练习5:作用域遮蔽
// 目标:理解内层代码块变量如何遮蔽外层变量
func exercise5() {
fmt.Println("\n=== 练习5:作用域遮蔽 ===")
// 外层变量
outer := "我是外层变量"
if true {
// 在if代码块内声明一个同名的变量,值为"我是内层变量"
// 这会遮蔽外层的outer变量
outer := ____
fmt.Printf("代码块内: %s\n", outer)
}
fmt.Printf("代码块外: %s\n", outer)
}
+152
View File
@@ -0,0 +1,152 @@
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) {
output := captureOutput(exercise1)
tests := []struct {
name string
expected string
}{
{"姓名检查", "姓名: 张三"},
{"年龄检查", "年龄: 25"},
{"学生检查", "是学生: true"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !strings.Contains(output, tt.expected) {
t.Errorf("期望输出包含 '%s', 但实际输出: %s", tt.expected, output)
}
})
}
}
func TestExercise2(t *testing.T) {
output := captureOutput(exercise2)
tests := []struct {
name string
expected string
}{
{"城市检查", "城市: 北京"},
{"价格检查", "价格: 99.50"},
{"坐标检查", "坐标: (10, 20, 30)"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !strings.Contains(output, tt.expected) {
t.Errorf("期望输出包含 '%s', 但实际输出: %s", tt.expected, output)
}
})
}
}
func TestExercise3(t *testing.T) {
output := captureOutput(exercise3)
tests := []struct {
name string
expected string
}{
{"用户名检查", "用户: go_learner"},
{"邮箱检查", "邮箱: learner@example.com"},
{"等级检查", "等级: 1"},
{"经验值检查", "经验值: 0.0"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !strings.Contains(output, tt.expected) {
t.Errorf("期望输出包含 '%s', 但实际输出: %s", tt.expected, output)
}
})
}
}
func TestExercise4(t *testing.T) {
output := captureOutput(exercise4)
tests := []struct {
name string
expected string
}{
{"全局变量检查", "全局变量 globalVar 的值: 100"},
{"局部变量检查", "局部变量 localVar 的值: 50"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !strings.Contains(output, tt.expected) {
t.Errorf("期望输出包含 '%s', 但实际输出: %s", tt.expected, output)
}
})
}
}
func TestExercise5(t *testing.T) {
output := captureOutput(exercise5)
tests := []struct {
name string
expected string
}{
{"代码块内检查", "代码块内: 我是内层变量"},
{"代码块外检查", "代码块外: 我是外层变量"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !strings.Contains(output, tt.expected) {
t.Errorf("期望输出包含 '%s', 但实际输出: %s", tt.expected, output)
}
})
}
}
// 辅助测试:验证全局变量值
func TestGlobalVar(t *testing.T) {
if globalVar != 100 {
t.Errorf("期望全局变量 globalVar 为 100, 实际为 %d", globalVar)
}
}
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)
}
}
}