一文熟悉 Go 的循环结构 —— for 循环

简介: 我是陈明勇,本文分享的知识是 Go 的循环结构。如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出!

耐心和持久胜过激烈和狂热。

前言

我是陈明勇,本文分享的知识是 Go 的循环结构。如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出!

循环结构

循环结构是指在程序中需要反复执行某个功能而设置的一种程序结构。有的编程语言,包含两种循环结构,一种是 for 循环,另一种是 while 循环,而在 Go 里面,有且只有一种循环 —— for 循环。接下来看一个示例:

func main() {
    sum := 0
    for num := 1; num <= 10; num++ {
  sum += num
    }
    println(sum) // 55
}
复制代码

1.png

上述代码实现的功能是在 1-10 之中累加求和,最后的结果为 55

  • 上图所示,for 循环分为四个部分,第一部分num := 1 为循环前置语句,在这一部分,我们一般都会定义一些变量,这些变量被使用于第二部分第三部分里。
  • 第二部分是条件判断表达式,也就是布尔表达式,多条件可以使用逻辑操作符进行连接。此部分的作用是判定循环是否继续下去,图中循环不终止的条件为 num <= 10。只要条件成立,就会去执行第三部分.
  • 第三部分为循环体,只要循环不终止,程序就会重复执行循环体里面的代码。上述例子中,循环体所做的事情就是累加 num 变量的值。
  • 第四部分为循环后置语句,这一部分通常会对第一部分所定义的变量进行更新,例如上述例子中,对 num 进行自增。

for 循环执行顺序是这样的:

  • 第一部分(只会执行一次)
  • 第二部分(若布尔表达式的值为 false 则终止循环,不进行第三第四部分)
  • 第三部分
  • 第四部分,然后返回第二部分继续执行。 对于上述四个部分,除了第三部分以外,其他部分都可以省略。如果只留第三部分,那么就形成死循环,以下为示例:
func main() {
        for {
  println("糟糕,死循环!")
        }
}
复制代码
  • 在一些场景下,我们会利用死循环去做一些特定的事,但是最终还是要跳出死循环的。如何跳出死循环,就涉及到接下来要讲的关键字 break

for-range

除了上面所讲的普通 for 循环的形式,Go 里面还支持一种 for 循环,为 for-range 循环,这是一种什么循环形式呢?我们来看看例子:

import "fmt"
func main() {
    nums := [4]int{1, 2, 3, 4}
    for i := 0; i < len(nums); i++ {
  fmt.Printf("下标:%d,元素:%d\n", i, nums[i])
    }
}
复制代码

上述代码,在循环前置语句中,声明数组的下标,然后循环体通过下标值打印数组的元素,我们来看看使用 for-range 的代码实现是怎么样的:

import "fmt"
func main() {
    nums := [4]int{1, 2, 3, 4}
    for i, num := range nums {
  fmt.Printf("下标:%d,元素:%d\n", i, num)
    }
}
复制代码

与普通 for 循环相比,for-range 的形式代码量少了很多,除了循环体保留了下来,其余部分都融入到了 for-range 的语义里。上述代码中,变量 i 为数组的下标索引,num 为数组中的元素值。如果我们所关注的只是数组的下标索引或者元素值,可以进行以下改造:

  • 只关注下标索引
import "fmt"
func main() {
        nums := [4]int{1, 2, 3, 4}
        for i := range nums {
            fmt.Printf("下标:%d\n", i)
        }
}
复制代码
  • 仅仅定义一个 i 变量。
  • 只关注元素值
import "fmt"
func main() {
        nums := [4]int{1, 2, 3, 4}
        for _, num := range nums {
            fmt.Printf("元素值:%d\n", num)
        }
}
复制代码
  • 索引位置使用 _ 代替,表示忽略下标索引的接收。
  • 下标索引和元素值都不关注
package main
func main() {
        nums := [4]int{1, 2, 3, 4}
        for range nums {
        }
}
复制代码

break 和 continue 关键字

breakcontinue 关键字用于控制 for 循环的代码流程,且只对最近的 for 循环有效(多层循环的情况下)。

  • break
    退出 for 循环,循环体后续代码不再执行。
  • continue
    终止本轮循环,循环体后续代码不再执行,进入下一轮循环。

示例

  • 循环遍历数组,如果在数组内找到元素值 6,则退出循环。
func main() {
        nums := [5]int{1, 2, 6, 3, 4}
        for _, num := range nums {
            if num == 6 {
                break
            }
            println("元素:", num)
        }
}
复制代码
  • 执行结果:
元素: 1
元素: 2
复制代码
  • 根据执行结果可知,遍历数组到元素 6 的时候,使用 break 关键字,循环就终止了,后面的元素 34 没有被打印出来。前面所提到的死循环也可以使用 break 关键字跳出循环。
  • 循环遍历数组,只打印奇数,忽略偶数。
func main() {
        nums := [5]int{1, 2, 6, 3, 4}
        for _, num := range nums {
            if num%2 == 0 {
                continue
            }
            println("元素:", num)
        }
}
复制代码
  • 执行结果:
元素: 1
元素: 3
复制代码
  • 遇到偶数元素,就使用关键字 continue 结束本轮循环,开始下一轮循环。

label

Go 语言中,label 语句的作用是标记跳转的目标。示例说明: 遍历二维数组,找到元素 3 后结束跳出整个循环。

func main() {
    nums := [][]int{
  {1, 2},
  {3, 4},
  {5, 6},
    }
    for i := 0; i < len(nums); i++ {
  println("第", i+1, "轮:")
  for j := 0; j < len(nums[i]); j++ {
      if nums[i][j] == 3 {
    break
      }
      println("元素值:", nums[i][j])
        }
    }
}
复制代码

执行结果:

第 1 轮:
元素值: 1
元素值: 2
第 2 轮:
第 3 轮:
元素值: 5
元素值: 6
复制代码

外层循环一共要循环三轮,根据结果可知,使用 break 关键字,并没有跳出整个循环。在第二轮循环之后,进入内层循环,找到元素 4break 关键字只终止了内层循环,外层循环的第三轮还会继续执行,这并不是我们想要的结果。要想达到目标结果,需要结合 label 语句实现:

func main() {
    nums := [][]int{
  {1, 2},
  {3, 4},
  {5, 6},
    }
outerLoop:
    for i := 0; i < len(nums); i++ {
  println("第", i+1, "轮:")
  for j := 0; j < len(nums[i]); j++ {
      if nums[i][j] == 3 {
    break outerLoop
      }
      println("元素值:", nums[i][j])
  }
    }
}
复制代码

执行结果:

第 1 轮:
元素值: 1
元素值: 2
第 2 轮:
复制代码

在第一层循环前面,使用 label 语句,用 outerLoop 进行标记,然后在 break 关键字后面加上这个标记,就能实现跳出整个循环。

小结

本文首先介绍了 Go 里面的普通 for 循环,然后由普通 for 循环引出了 for-range 循环,对于数组、切片、Map 等复合数据结构,遍历方式使用 for-range 的形式会更好,特殊的复合数据类型如 Map,遍历方式也只能用 for-range 的形式。本文还提到了 breakcontinuelabel 关键字,通过案例介绍了它们的使用场景。

目录
相关文章
|
3月前
|
Go
Go 1.22 for 循环的两处重要更新
本文介绍了 Go 1.22 版本对 for 循环所做的两处重要更新:循环的每次迭代都会创建新变量 和 循环支持对整数范围进行迭代。 - 循环的每次迭代都会创建新变量,有效避免了以往版本中常见的闭包陷阱,提高了代码的安全性和可预测性。 - 循环支持对整数范围进行迭代,极大地增强了 for 循环的灵活性,使得编写计数循环更加直接和简洁。
55 1
Go 1.22 for 循环的两处重要更新
|
5月前
|
JSON JavaScript Go
Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
掌握 Go 语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解 Go 基础知识的好起点是查阅 Go 官方文档
502 2
|
7天前
|
Go 索引
【Go 语言专栏】Go 语言中的条件语句与循环结构
【4月更文挑战第30天】本文探讨了Go语言中的条件语句(if/else, switch)和循环结构(for/range)。通过示例代码,展示了如何判断素数、计算阶乘及遍历数组。这些基础结构是Go编程的关键,有助于编写高效简洁的代码。
|
13天前
|
Go 开发者
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
【4月更文挑战第21天】本文介绍了Go语言中的流程控制语句,包括`if`、`switch`和`for`循环。`if`语句支持简洁的语法和初始化语句,但需注意比较运算符的使用。`switch`语句提供多分支匹配,可省略`break`,同时支持不带表达式的形式。`for`循环有多种形式,如基本循环和`for-range`遍历,遍历时修改原集合可能导致未定义行为。理解并避免易错点能提高代码质量和稳定性。通过实践代码示例,可以更好地掌握Go语言的流程控制。
17 3
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
|
14天前
|
程序员 Go API
【Go语言快速上手(二)】 分支与循环&函数讲解
【Go语言快速上手(二)】 分支与循环&函数讲解
|
1月前
|
Go C语言 索引
掌握Go语言:探索Go语言中的循环奇妙世界,从基础到实战(13)
掌握Go语言:探索Go语言中的循环奇妙世界,从基础到实战(13)
|
3月前
|
Go 开发者 索引
Go语言中的循环控制结构解析
【2月更文挑战第3天】本文将详细探讨Go语言中的循环控制结构,包括`for`循环、`range`循环以及`无限循环`的使用方法和适用场景。通过掌握这些循环结构,Go语言开发者能够更加高效地进行迭代操作、处理集合数据以及实现复杂的控制逻辑。
|
4月前
|
编译器 Go
go语言第二章循环结构(for循环)
go语言第二章循环结构(for循环)
27 0
|
5月前
|
存储 Go 索引
Go 语言中 For 循环:语法、使用方法和实例教程
for循环用于多次执行特定的代码块,每次都可以使用不同的值。每次循环执行都称为一次迭代。for循环可以包含最多三个语句: 语法
48 0
|
3天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
25 0

相关实验场景

更多