Update
This commit is contained in:
@@ -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` 验证答案。
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user