#Go Loop Statements
Loop statements are used to repeatedly execute a block of code until a certain condition is met. Go has only one loop keyword, for, but it comes in several forms to suit different looping needs.
#🔄 Basic Forms of the for Loop
#Classic Three-Part for Loop
package main
import "fmt"
func main() {
// 基本的 for 循环:初始化; 条件; 后置语句
fmt.Println("数字 1 到 5:")
for i := 1; i <= 5; i++ {
fmt.Printf("%d ", i)
}
fmt.Println()
// 倒序循环
fmt.Println("倒数 5 到 1:")
for i := 5; i >= 1; i-- {
fmt.Printf("%d ", i)
}
fmt.Println()
// 步长不为 1 的循环
fmt.Println("偶数 2 到 10:")
for i := 2; i <= 10; i += 2 {
fmt.Printf("%d ", i)
}
fmt.Println()
// 嵌套循环 - 乘法表
fmt.Println("\n九九乘法表:")
for i := 1; i <= 9; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d*%d=%d ", j, i, i*j)
}
fmt.Println()
}
}#Conditional Loop (Similar to while)
func main() {
// 省略初始化和后置语句,只保留条件
count := 0
fmt.Println("条件循环:")
for count < 5 {
fmt.Printf("count = %d\n", count)
count++
}
// 无限循环(需要用 break 跳出)
fmt.Println("\n无限循环示例:")
counter := 0
for {
if counter >= 3 {
break // 跳出循环
}
fmt.Printf("无限循环第 %d 次\n", counter+1)
counter++
}
// 模拟 do-while 循环
fmt.Println("\n模拟 do-while:")
num := 10
for {
fmt.Printf("num = %d\n", num)
num--
if num < 8 {
break
}
}
}#🎯 range Loops
#Iterating Over Slices and Arrays
func main() {
// 遍历切片
fruits := []string{"苹果", "香蕉", "橙子", "葡萄"}
// 方式1:获取索引和值
fmt.Println("遍历水果(索引和值):")
for index, fruit := range fruits {
fmt.Printf("索引 %d: %s\n", index, fruit)
}
// 方式2:只获取索引
fmt.Println("\n只获取索引:")
for index := range fruits {
fmt.Printf("索引 %d\n", index)
}
// 方式3:只获取值
fmt.Println("\n只获取值:")
for _, fruit := range fruits {
fmt.Printf("水果: %s\n", fruit)
}
// 遍历数组
numbers := [5]int{10, 20, 30, 40, 50}
fmt.Println("\n遍历数组:")
for i, num := range numbers {
fmt.Printf("numbers[%d] = %d\n", i, num)
}
}#Iterating Over Maps
func main() {
// 遍历 map
studentGrades := map[string]int{
"Alice": 95,
"Bob": 87,
"Carol": 92,
"David": 78,
}
fmt.Println("学生成绩:")
for name, grade := range studentGrades {
fmt.Printf("%s: %d分\n", name, grade)
}
// 只获取键
fmt.Println("\n学生姓名:")
for name := range studentGrades {
fmt.Printf("学生: %s\n", name)
}
// 只获取值
fmt.Println("\n所有成绩:")
for _, grade := range studentGrades {
fmt.Printf("成绩: %d\n", grade)
}
// 注意:map 的遍历顺序是随机的
fmt.Println("\n多次遍历顺序可能不同:")
for i := 0; i < 3; i++ {
fmt.Printf("第%d次遍历: ", i+1)
for name := range studentGrades {
fmt.Printf("%s ", name)
}
fmt.Println()
}
}#Iterating Over Strings
import "unicode/utf8"
func main() {
// 遍历字符串(按字节)
str := "Hello, 世界!"
fmt.Println("按字节遍历:")
for i := 0; i < len(str); i++ {
fmt.Printf("字节 %d: %c (0x%02x)\n", i, str[i], str[i])
}
// 遍历字符串(按字符)
fmt.Println("\n按字符遍历:")
for index, char := range str {
fmt.Printf("位置 %d: %c (Unicode: %U)\n", index, char, char)
}
// 统计字符数
fmt.Printf("\n字符串长度: %d 字节\n", len(str))
fmt.Printf("字符数量: %d 个字符\n", utf8.RuneCountInString(str))
// 中文字符串示例
chinese := "你好世界"
fmt.Printf("\n中文字符串: %s\n", chinese)
fmt.Printf("字节长度: %d\n", len(chinese))
for i, char := range chinese {
fmt.Printf("位置 %d: %c\n", i, char)
}
}#Iterating Over Channels
func main() {
// 创建并填充通道
ch := make(chan int, 5)
// 发送数据到通道
go func() {
for i := 1; i <= 5; i++ {
ch <- i * i // 发送平方数
}
close(ch) // 关闭通道
}()
// 遍历通道
fmt.Println("从通道接收数据:")
for value := range ch {
fmt.Printf("接收到: %d\n", value)
}
fmt.Println("通道已关闭,遍历结束")
}#🛑 Loop Control Statements
#break Statement
func main() {
// break 跳出当前循环
fmt.Println("使用 break 跳出循环:")
for i := 1; i <= 10; i++ {
if i == 6 {
break // 当 i 等于 6 时跳出循环
}
fmt.Printf("%d ", i)
}
fmt.Println("\n循环结束")
// 在嵌套循环中使用 break
fmt.Println("\n嵌套循环中的 break:")
for i := 1; i <= 3; i++ {
fmt.Printf("外层循环 i = %d\n", i)
for j := 1; j <= 3; j++ {
if j == 2 {
break // 只跳出内层循环
}
fmt.Printf(" 内层循环 j = %d\n", j)
}
}
// 查找数组中的元素
numbers := []int{1, 3, 5, 7, 9, 2, 4, 6, 8}
target := 7
fmt.Printf("\n在数组中查找 %d:\n", target)
for i, num := range numbers {
if num == target {
fmt.Printf("找到 %d 在索引 %d 位置\n", target, i)
break
}
fmt.Printf("检查索引 %d: %d\n", i, num)
}
}#continue Statement
func main() {
// continue 跳过当前迭代,继续下一次迭代
fmt.Println("打印奇数 (1-10):")
for i := 1; i <= 10; i++ {
if i%2 == 0 {
continue // 跳过偶数
}
fmt.Printf("%d ", i)
}
fmt.Println()
// 处理数组时跳过特定值
scores := []int{85, -1, 92, 88, -1, 76, 94}
validScores := 0
totalScore := 0
fmt.Println("\n处理成绩(跳过无效成绩 -1):")
for i, score := range scores {
if score == -1 {
fmt.Printf("索引 %d: 跳过无效成绩\n", i)
continue
}
fmt.Printf("索引 %d: 有效成绩 %d\n", i, score)
validScores++
totalScore += score
}
if validScores > 0 {
average := float64(totalScore) / float64(validScores)
fmt.Printf("平均成绩: %.2f\n", average)
}
}#Labels and goto
func main() {
// 使用标签控制嵌套循环
fmt.Println("使用标签的嵌套循环:")
OuterLoop: // 标签
for i := 1; i <= 3; i++ {
for j := 1; j <= 3; j++ {
if i == 2 && j == 2 {
fmt.Printf("在 i=%d, j=%d 时跳出所有循环\n", i, j)
break OuterLoop // 跳出到标签位置
}
fmt.Printf("i=%d, j=%d\n", i, j)
}
}
fmt.Println("嵌套循环结束")
// continue 配合标签
fmt.Println("\n使用标签的 continue:")
ContinueOuter:
for i := 1; i <= 3; i++ {
for j := 1; j <= 3; j++ {
if j == 2 {
fmt.Printf("在 i=%d, j=%d 时跳过外层循环的剩余内层循环\n", i, j)
continue ContinueOuter
}
fmt.Printf("i=%d, j=%d\n", i, j)
}
fmt.Printf("外层循环 i=%d 的内层循环完成\n", i)
}
}#🎯 Practical Application Examples
#Data Processing and Statistics
import (
"fmt"
"math"
"sort"
)
func main() {
// 学生成绩数据
students := map[string][]int{
"Alice": {85, 92, 78, 88, 90},
"Bob": {76, 81, 69, 85, 79},
"Carol": {95, 89, 92, 96, 93},
"David": {72, 68, 75, 71, 77},
}
// 处理每个学生的成绩
for name, scores := range students {
fmt.Printf("\n学生: %s\n", name)
fmt.Printf("原始成绩: %v\n", scores)
// 计算总分和平均分
total := 0
for _, score := range scores {
total += score
}
average := float64(total) / float64(len(scores))
// 找最高分和最低分
maxScore := scores[0]
minScore := scores[0]
for _, score := range scores {
if score > maxScore {
maxScore = score
}
if score < minScore {
minScore = score
}
}
// 计算方差
variance := 0.0
for _, score := range scores {
diff := float64(score) - average
variance += diff * diff
}
variance /= float64(len(scores))
standardDev := math.Sqrt(variance)
// 计算等级
grade := calculateGrade(average)
fmt.Printf("总分: %d\n", total)
fmt.Printf("平均分: %.2f\n", average)
fmt.Printf("最高分: %d\n", maxScore)
fmt.Printf("最低分: %d\n", minScore)
fmt.Printf("标准差: %.2f\n", standardDev)
fmt.Printf("等级: %s\n", grade)
}
// 班级整体统计
fmt.Println("\n=== 班级整体统计 ===")
allScores := []float64{}
for _, scores := range students {
total := 0
for _, score := range scores {
total += score
}
average := float64(total) / float64(len(scores))
allScores = append(allScores, average)
}
// 排序平均分
sort.Float64s(allScores)
fmt.Printf("平均分排序: %.2f\n", allScores)
classTotal := 0.0
for _, avg := range allScores {
classTotal += avg
}
classAverage := classTotal / float64(len(allScores))
fmt.Printf("班级平均分: %.2f\n", classAverage)
}
func calculateGrade(average float64) string {
switch {
case average >= 90:
return "A"
case average >= 80:
return "B"
case average >= 70:
return "C"
case average >= 60:
return "D"
default:
return "F"
}
}#Prime Number Generator
import "math"
func main() {
// 生成前20个素数
fmt.Println("前20个素数:")
primes := generatePrimes(20)
for i, prime := range primes {
fmt.Printf("第%d个素数: %d\n", i+1, prime)
}
// 找100以内的所有素数
fmt.Println("\n100以内的素数:")
primesUnder100 := sieveOfEratosthenes(100)
for i, prime := range primesUnder100 {
if i > 0 && i%10 == 0 {
fmt.Println()
}
fmt.Printf("%3d ", prime)
}
fmt.Println()
}
// 生成前 n 个素数
func generatePrimes(n int) []int {
primes := []int{}
num := 2
for len(primes) < n {
if isPrime(num) {
primes = append(primes, num)
}
num++
}
return primes
}
// 判断是否为素数
func isPrime(n int) bool {
if n < 2 {
return false
}
if n == 2 {
return true
}
if n%2 == 0 {
return false
}
// 只需检查到 sqrt(n)
sqrtN := int(math.Sqrt(float64(n)))
for i := 3; i <= sqrtN; i += 2 {
if n%i == 0 {
return false
}
}
return true
}
// 埃拉托斯特尼筛法
func sieveOfEratosthenes(max int) []int {
// 创建布尔数组
isPrime := make([]bool, max+1)
for i := range isPrime {
isPrime[i] = true
}
isPrime[0] = false
isPrime[1] = false
// 筛法
for i := 2; i*i <= max; i++ {
if isPrime[i] {
// 标记 i 的倍数为非素数
for j := i * i; j <= max; j += i {
isPrime[j] = false
}
}
}
// 收集素数
primes := []int{}
for i := 2; i <= max; i++ {
if isPrime[i] {
primes = append(primes, i)
}
}
return primes
}#Text Processing and Analysis
import (
"fmt"
"strings"
"unicode"
)
func main() {
text := `Go语言是Google开发的开源编程语言。
它具有简洁的语法、高效的性能和强大的并发能力。
Go适用于云原生应用、微服务、Web开发等多个领域。
学习Go语言,你可以构建现代化的软件系统。`
fmt.Println("原文本:")
fmt.Println(text)
fmt.Println()
// 文本统计
analyzer := NewTextAnalyzer(text)
analyzer.Analyze()
analyzer.PrintStatistics()
}
type TextAnalyzer struct {
text string
lines []string
words []string
characters int
letters int
digits int
spaces int
punctuation int
wordCount map[string]int
}
func NewTextAnalyzer(text string) *TextAnalyzer {
return &TextAnalyzer{
text: text,
wordCount: make(map[string]int),
}
}
func (ta *TextAnalyzer) Analyze() {
// 按行分割
ta.lines = strings.Split(ta.text, "\n")
// 字符统计
for _, char := range ta.text {
ta.characters++
switch {
case unicode.IsLetter(char):
ta.letters++
case unicode.IsDigit(char):
ta.digits++
case unicode.IsSpace(char):
ta.spaces++
case unicode.IsPunct(char):
ta.punctuation++
}
}
// 单词统计
for _, line := range ta.lines {
words := strings.Fields(line)
for _, word := range words {
// 清理标点符号
cleanWord := ""
for _, char := range word {
if unicode.IsLetter(char) || unicode.IsDigit(char) {
cleanWord += string(char)
}
}
if cleanWord != "" {
cleanWord = strings.ToLower(cleanWord)
ta.words = append(ta.words, cleanWord)
ta.wordCount[cleanWord]++
}
}
}
}
func (ta *TextAnalyzer) PrintStatistics() {
fmt.Println("=== 文本分析结果 ===")
fmt.Printf("行数: %d\n", len(ta.lines))
fmt.Printf("总字符数: %d\n", ta.characters)
fmt.Printf("字母数: %d\n", ta.letters)
fmt.Printf("数字数: %d\n", ta.digits)
fmt.Printf("空格数: %d\n", ta.spaces)
fmt.Printf("标点符号数: %d\n", ta.punctuation)
fmt.Printf("单词总数: %d\n", len(ta.words))
fmt.Printf("不重复单词数: %d\n", len(ta.wordCount))
// 词频统计(显示前10个)
fmt.Println("\n词频统计 (前10个):")
type wordFreq struct {
word string
count int
}
var frequencies []wordFreq
for word, count := range ta.wordCount {
frequencies = append(frequencies, wordFreq{word, count})
}
// 按频率排序
for i := 0; i < len(frequencies)-1; i++ {
for j := i + 1; j < len(frequencies); j++ {
if frequencies[i].count < frequencies[j].count {
frequencies[i], frequencies[j] = frequencies[j], frequencies[i]
}
}
}
// 显示前10个
maxDisplay := 10
if len(frequencies) < maxDisplay {
maxDisplay = len(frequencies)
}
for i := 0; i < maxDisplay; i++ {
fmt.Printf("%d. %s: %d次\n", i+1, frequencies[i].word, frequencies[i].count)
}
}#💡 Performance Optimization Tips
#Loop Optimization
import (
"fmt"
"time"
)
func main() {
// 测试数据
size := 1000000
data := make([]int, size)
for i := range data {
data[i] = i
}
// 方法1:普通循环
start := time.Now()
sum1 := 0
for i := 0; i < len(data); i++ {
sum1 += data[i]
}
duration1 := time.Since(start)
// 方法2:range 循环
start = time.Now()
sum2 := 0
for _, value := range data {
sum2 += value
}
duration2 := time.Since(start)
// 方法3:预先计算长度
start = time.Now()
sum3 := 0
length := len(data)
for i := 0; i < length; i++ {
sum3 += data[i]
}
duration3 := time.Since(start)
fmt.Printf("普通循环: 结果=%d, 耗时=%v\n", sum1, duration1)
fmt.Printf("range循环: 结果=%d, 耗时=%v\n", sum2, duration2)
fmt.Printf("预计算长度: 结果=%d, 耗时=%v\n", sum3, duration3)
// 避免在循环中进行重复计算
fmt.Println("\n避免重复计算示例:")
// ❌ 不好的做法
start = time.Now()
count1 := 0
for i := 0; i < 10000; i++ {
for j := 0; j < len(data)/1000; j++ { // 每次都计算 len(data)
count1++
}
}
badDuration := time.Since(start)
// ✅ 好的做法
start = time.Now()
count2 := 0
innerLen := len(data) / 1000 // 预先计算
for i := 0; i < 10000; i++ {
for j := 0; j < innerLen; j++ {
count2++
}
}
goodDuration := time.Since(start)
fmt.Printf("重复计算: 次数=%d, 耗时=%v\n", count1, badDuration)
fmt.Printf("预先计算: 次数=%d, 耗时=%v\n", count2, goodDuration)
fmt.Printf("性能提升: %.2fx\n", float64(badDuration)/float64(goodDuration))
}#🎓 Summary
In this chapter, we comprehensively learned about Go loop statements:
- ✅ for Loop: three-part loop, conditional loop, infinite loop
- ✅ range Loop: iterating over slices, arrays, maps, strings, and channels
- ✅ Loop Control: break, continue, and label-based control
- ✅ Practical Applications: data statistics, prime number generation, text analysis
- ✅ Performance Optimization: loop optimization techniques and best practices
Go's for loop is powerful and flexible. Combined with the range keyword, it provides an elegant way to iterate over various data structures.
Next, we will learn Go Functions to understand how to organize and reuse code.
::: tip Loop Usage Suggestions
- Prefer range loops when iterating over data structures
- Avoid repeated complex calculations inside loops
- Use break and continue appropriately to control loop flow
- Be mindful of the performance impact of nested loops :::