https://www.runoob.com/go/go-operators.html
在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控
制语句。
程序从上到下逐行地执行,中间没有任何判断和跳转。一个案例说明,必须下面的代码中,没有判断,也没有跳转.因此程序按照默认的流程执行,即顺
序控制
Golang 中定义变量时采用合法的前向引用。如:
func main() {
var num1 int = 10 //声明了 num1
var num2 int = num1 + 20 //使用 num1
fmt.Println(num2)
}
错误形式:
func main() {
var num2 int = num1 + 20 //使用 num1
var num1 int = 10 //声明 num1 (×)
fmt.Println(num2)
}
分支控制就是让程序有选择执行。有下面三种形式
基本语法
使用 if 判断一个数变量的大小:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 10
/* 使用 if 语句判断布尔表达式 */
if a < 20 {
/* 如果条件为 true 则执行以下语句 */
fmt.Printf("a 小于 20\n" )
}
fmt.Printf("a 的值为 : %d\n", a)
}
以上代码执行结果为:
a 小于 20
a 的值为 : 10
Go 语言条件语句
if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。
Go 编程语言中 if…else 语句的语法如下:
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
} else {
/* 在布尔表达式为 false 时执行 */
}
If 在布尔表达式为 true 时,其后紧跟的语句块执行,如果为 false 则执行 else 语句块。
流程图如下:
使用 if else 判断一个数的大小:
package main
import "fmt"
func main() {
/* 局部变量定义 */
var a int = 100;
/* 判断布尔表达式 */
if a < 20 {
/* 如果条件为 true 则执行以下语句 */
fmt.Printf("a 小于 20\n" );
} else {
/* 如果条件为 false 则执行以下语句 */
fmt.Printf("a 不小于 20\n" );
}
fmt.Printf("a 的值为 : %d\n", a);
}
以上代码执行结果为:
a 不小于 20
a 的值为 : 100
Go 语言条件语句
你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。
Go 编程语言中 if…else 语句的语法如下:
if 布尔表达式 1 {
/* 在布尔表达式 1 为 true 时执行 */
if 布尔表达式 2 {
/* 在布尔表达式 2 为 true 时执行 */
}
}
你可以以同样的方式在 if 语句中嵌套 else if…else 语句
嵌套使用 if 语句:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 100
var b int = 200
/* 判断条件 */
if a == 100 {
/* if 条件语句为 true 执行 */
if b == 200 {
/* if 条件语句为 true 执行 */
fmt.Printf("a 的值为 100 , b 的值为 200\n" );
}
}
fmt.Printf("a 值为 : %d\n", a );
fmt.Printf("b 值为 : %d\n", b );
以上代码执行结果为:
a 的值为 100 , b 的值为 200
a 值为 : 100
b 值为 : 200
Go 语言条件语句
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止。
switch 语句执行的过程从上至下,直到找到匹配项,匹配项后面也不需要再加 break。
switch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case,如果我们需要执行后面的 case,可以使用 fallthrough 。
Go 编程语言中 switch 语句的语法如下:
switch var1 {
case val1:
...
case val2:
...
default:
...
}
变量 var1 可以是任何类型,而 val1 和 val2 则可以是同类型的任意值。类型不被局限于常量或整数,但必须是相同的类型;或者最终结果为相同类型的表达式。
您可以同时测试多个可能符合条件的值,使用逗号分割它们,例如:case val1, val2, val3。
流程图:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var grade string = "B"
var marks int = 90
switch marks {
case 90: grade = "A"
case 80: grade = "B"
case 50,60,70 : grade = "C"
default: grade = "D"
}
switch {
case grade == "A" :
fmt.Printf("优秀!\n" )
case grade == "B", grade == "C" :
fmt.Printf("良好\n" )
case grade == "D" :
fmt.Printf("及格\n" )
case grade == "F":
fmt.Printf("不及格\n" )
default:
fmt.Printf("差\n" );
}
fmt.Printf("你的等级是 %s\n", grade );
以上代码执行结果为:
优秀!
你的等级是 A
switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。
Type Switch 语法格式如下:
switch x.(type){
case type:
statement(s);
case type:
statement(s);
/* 你可以定义任意个数的case */
default: /* 可选 */
statement(s);
}
package main
import "fmt"
func main() {
var x interface{}
switch i := x.(type) {
case nil:
fmt.Printf(" x 的类型 :%T",i)
case int:
fmt.Printf("x 是 int 型")
case float64:
fmt.Printf("x 是 float64 型")
case func(int) float64:
fmt.Printf("x 是 func(int) 型")
case bool, string:
fmt.Printf("x 是 bool 或 string 型" )
default:
fmt.Printf("未知型")
}
}
以上代码执行结果为:
x 的类型 :
使用 fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true。
package main
import "fmt"
func main() {
switch {
case false:
fmt.Println("1、case 条件语句为 false")
fallthrough
case true:
fmt.Println("2、case 条件语句为 true")
fallthrough
case false:
fmt.Println("3、case 条件语句为 false")
fallthrough
case true:
fmt.Println("4、case 条件语句为 true")
case false:
fmt.Println("5、case 条件语句为 false")
fallthrough
default:
fmt.Println("6、默认 case")
}
}
以上代码执行结果为:
2、case 条件语句为 true
3、case 条件语句为 false
4、case 条件语句为 true
从以上代码输出的结果可以看出:switch 从第一个判断表达式为 true 的 case 开始执行,如果 case 带有 fallthrough,程序会继续执行下一条 case,且它不会去判断下一个 case 的表达式是否为 true。
Go 语言条件语句
select 是 Go 中的一个控制结构,类似于 switch 语句。
select 语句只能用于通道操作,每个 case 必须是一个通道操作,要么是发送要么是接收。
select 语句会监听所有指定的通道上的操作,一旦其中一个通道准备好就会执行相应的代码块。
如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。如果所有通道都没有准备好,那么执行 default 块中的代码。
Go 编程语言中 select 语句的语法如下:
select {
case <- channel1:
// 执行的代码
case value := <- channel2:
// 执行的代码
case channel3 <- value:
// 执行的代码
// 你可以定义任意数量的 case
default:
// 所有通道都没有准备好,执行的代码
}
以下描述了 select 语句的语法:
每个 case 都必须是一个通道
所有 channel 表达式都会被求值
所有被发送的表达式都会被求值
如果任意某个通道可以进行,它就执行,其他被忽略。
如果有多个 case 都可以运行,select 会随机公平地选出一个执行,其他不会执行。
否则:
select 语句应用演示:
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
c1 <- "one"
}()
go func() {
time.Sleep(2 * time.Second)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
以上代码执行结果为:
received one
received two
以上实例中,我们创建了两个通道 c1 和 c2。
select 语句等待两个通道的数据。如果接收到 c1 的数据,就会打印 “received one”;如果接收到 c2 的数据,就会打印 “received two”。
以下实例中,我们定义了两个通道,并启动了两个协程(Goroutine)从这两个通道中获取数据。在 main 函数中,我们使用 select 语句在这两个通道中进行非阻塞的选择,如果两个通道都没有可用的数据,就执行 default 子句中的语句。
以下实例执行后会不断地从两个通道中获取到的数据,当两个通道都没有可用的数据时,会输出 “no message received”。
package main
import "fmt"
func main() {
// 定义两个通道
ch1 := make(chan string)
ch2 := make(chan string)
// 启动两个 goroutine,分别从两个通道中获取数据
go func() {
for {
ch1 <- "from 1"
}
}()
go func() {
for {
ch2 <- "from 2"
}
}()
// 使用 select 语句非阻塞地从两个通道中获取数据
for {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
default:
// 如果两个通道都没有可用的数据,则执行这里的语句
fmt.Println("no message received")
}
}
}
总结了什么情况下使用 switch ,什么情况下使用 if
在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。
以下为大多编程语言循环程序的流程图:
Go 语言提供了以下几种类型循环处理语句:
循环类型 | 描述 |
---|---|
for 循环 | 重复执行语句块 |
循环嵌套 | 在 for 循环中嵌套一个或多个 for 循环 |
Go 语言循环语句
for 循环是一个循环控制结构,可以执行指定次数的循环。
Go 语言的 For 循环有 3 种形式,只有其中的一种使用分号。
和 C 语言的 for 一样:
for init; condition; post { }
和 C 的 while 一样:
for condition { }
和 C 的 for(; 一样:
for { }
init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
for语句执行过程如下:
1、先对表达式 1 赋初值;
2、判别赋值表达式 init 是否满足给定条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
for key, value := range oldMap {
newMap[key] = value
}
以上代码中的 key 和 value 是可以省略。
如果只想读取 key,格式如下:
for key := range oldMap
或者这样:
for key, _ := range oldMap
如果只想读取 value,格式如下:
for _, value := range oldMap
for 语句语法流程如下图所示:
计算 1 到 10 的数字之和:
package main
import "fmt"
func main() {
sum := 0
for i := 0; i <= 10; i++ {
sum += i
}
fmt.Println(sum)
}
输出结果为:
55
init 和 post 参数是可选的,我们可以直接省略它,类似 While 语句。
以下实例在 sum 小于 10 的时候计算 sum 自相加后的值:
package main
import "fmt"
func main() {
sum := 1
for ; sum <= 10; {
sum += sum
}
fmt.Println(sum)
// 这样写也可以,更像 While 语句形式
for sum <= 10{
sum += sum
}
fmt.Println(sum)
}
输出结果为:
16
16
无限循环:
package main
import "fmt"
func main() {
sum := 0
for {
sum++ // 无限循环下去
}
fmt.Println(sum) // 无法输出
}
要停止无限循环,可以在命令窗口按下ctrl-c 。
For-each range 循环
这种格式的循环可以对字符串、数组、切片等进行迭代输出元素。
package main
import "fmt"
func main() {
strings := []string{"google", "runoob"}
for i, s := range strings {
fmt.Println(i, s)
}
numbers := [6]int{1, 2, 3, 5}
for i,x:= range numbers {
fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
}
}
以上实例运行输出结果为:
0 google
1 runoob
第 0 位 x 的值 = 1
第 1 位 x 的值 = 2
第 2 位 x 的值 = 3
第 3 位 x 的值 = 5
第 4 位 x 的值 = 0
第 5 位 x 的值 = 0
for 循环的 range 格式可以省略 key 和 value,如下实例:
package main
import "fmt"
func main() {
map1 := make(map[int]float32)
map1[1] = 1.0
map1[2] = 2.0
map1[3] = 3.0
map1[4] = 4.0
// 读取 key 和 value
for key, value := range map1 {
fmt.Printf("key is: %d - value is: %f\n", key, value)
}
// 读取 key
for key := range map1 {
fmt.Printf("key is: %d\n", key)
}
// 读取 value
for _, value := range map1 {
fmt.Printf("value is: %f\n", value)
}
}
以上实例运行输出结果为:
key is: 4 - value is: 4.000000
key is: 1 - value is: 1.000000
key is: 2 - value is: 2.000000
key is: 3 - value is: 3.000000
key is: 1
key is: 2
key is: 3
key is: 4
value is: 1.000000
value is: 2.000000
value is: 3.000000
value is: 4.000000
Go 语言循环语句
Go 语言允许用户在循环内使用循环。接下来我们将为大家介绍嵌套循环的使用。
基本介绍
以下为 Go 语言嵌套循环的格式:
for [condition | ( init; condition; increment ) | Range]
{
for [condition | ( init; condition; increment ) | Range]
{
statement(s);
}
statement(s);
}
以下实例使用循环嵌套来输出 2 到 100 间的素数:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var i, j int
for i=2; i < 100; i++ {
for j=2; j <= (i/j); j++ {
if(i%j==0) {
break; // 如果发现因子,则不是素数
}
}
if(j > (i/j)) {
fmt.Printf("%d 是素数\n", i);
}
}
}
以上实例运行输出结果为:
2 是素数
3 是素数
5 是素数
7 是素数
11 是素数
13 是素数
17 是素数
19 是素数
23 是素数
29 是素数
循环控制语句可以控制循环体内语句的执行过程。
GO 语言支持以下几种循环控制语句:
控制语句 | 描述 |
---|---|
break 语句 | 经常用于中断当前 for 循环或跳出 switch 语句 |
continue 语句 | 跳过当前循环的剩余语句,然后继续进行下一轮循环。 |
goto 语句 | 将控制转移到被标记的语句。 |
Go语言循环语句
在 Go 语言中,break 语句用于终止当前循环或者 switch 语句的执行,并跳出该循环或者 switch 语句的代码块。
break 语句可以用于以下几个方面:。
用于循环语句中跳出循环,并开始执行循环之后的语句。
break 在 switch 语句中在执行一条 case 后跳出语句的作用。
break 可应用在 select 语句中。
在多重循环中,可以用标号 label 标出想 break 的循环。
break 语法格式如下:
break
break 语句流程图如下:
在 for 循环中使用 break:
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
if i == 5 {
break // 当 i 等于 5 时跳出循环
}
fmt.Println(i)
}
}
输出结果:
0
1
2
3
4
在变量 a 大于 15 的时候跳出循环:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 10
/* for 循环 */
for a < 20 {
fmt.Printf("a 的值为 : %d\n", a);
a++
if a > 15 {
/* a 大于 15 时使用 break 语句跳出循环 */
break
}
}
}
以上实例中当 a 的值大于 15 时,break 语句被执行,整个循环被终止。执行结果为:
a 的值为 : 10
a 的值为 : 11
a 的值为 : 12
a 的值为 : 13
a 的值为 : 14
a 的值为 : 15
以下实例有多重循环,演示了使用标记和不使用标记的区别:
package main
import "fmt"
func main() {
// 不使用标记
fmt.Println("---- break ----")
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
break
}
}
// 使用标记
fmt.Println("---- break label ----")
re:
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
break re
}
}
}
以上实例执行结果为:
---- break ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11
---- break label ----
i: 1
i2: 11
在 switch 语句中使用 break:
import "fmt"
func main() {
day := "Tuesday"
switch day {
case "Monday":
fmt.Println("It's Monday.")
case "Tuesday":
fmt.Println("It's Tuesday.")
break // 跳出 switch 语句
case "Wednesday":
fmt.Println("It's Wednesday.")
}
}
输出结果:
It's Tuesday.
在 select 语句中使用 break:
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
time.Sleep(2 * time.Second)
ch1 <- 1
}()
go func() {
time.Sleep(1 * time.Second)
ch2 <- 2
}()
select {
case <-ch1:
fmt.Println("Received from ch1.")
case <-ch2:
fmt.Println("Received from ch2.")
break // 跳出 select 语句
}
}
输出结果:
Received from ch2.
在 Go 语言中,break 语句在 select 语句中的应用是相对特殊的。由于 select 语句的特性,break 语句并不能直接用于跳出 select 语句本身,因为 select 语句是非阻塞的,它会一直等待所有的通信操作都准备就绪。如果需要提前结束 select 语句的执行,可以使用 return 或者 goto 语句来达到相同的效果。
以下实例,展示了在 select 语句中使用 return 来提前结束执行的情况:
package main
import (
"fmt"
"time"
)
func process(ch chan int) {
for {
select {
case val := <-ch:
fmt.Println("Received value:", val)
// 执行一些逻辑
if val == 5 {
return // 提前结束 select 语句的执行
}
default:
fmt.Println("No value received yet.")
time.Sleep(500 * time.Millisecond)
}
}
}
func main() {
ch := make(chan int)
go process(ch)
time.Sleep(2 * time.Second)
ch <- 1
time.Sleep(1 * time.Second)
ch <- 3
time.Sleep(1 * time.Second)
ch <- 5
time.Sleep(1 * time.Second)
ch <- 7
time.Sleep(2 * time.Second)
}
以上实例中,process 函数在一个无限循环中使用 select 语句等待通道 ch 上的数据。当接收到数据时,会执行一些逻辑。当接收到的值等于 5 时,使用 return 提前结束 select 语句的执行。
输出结果:
No value received yet.
No value received yet.
Received value: 1
No value received yet.
Received value: 3
No value received yet.
Received value: 5
Go 语言循环语句
Go 语言的 continue 语句 有点像 break 语句。但是 continue 不是跳出循环,而是跳过当前循环执行下一次循环语句。
for 循环中,执行 continue 语句会触发 for 增量语句的执行。
在多重循环中,可以用标号 label 标出想 continue 的循环。
continue 语法格式如下:
continue;
continue 语句流程图如下:
在变量 a 等于 15 的时候跳过本次循环执行下一次循环:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 10
/* for 循环 */
for a < 20 {
if a == 15 {
/* 跳过此次循环 */
a = a + 1;
continue;
}
fmt.Printf("a 的值为 : %d\n", a);
a++;
}
}
以上实例执行结果为:
a 的值为 : 10
a 的值为 : 11
a 的值为 : 12
a 的值为 : 13
a 的值为 : 14
a 的值为 : 16
a 的值为 : 17
a 的值为 : 18
a 的值为 : 19
以下实例有多重循环,演示了使用标记和不使用标记的区别:
package main
import "fmt"
func main() {
// 不使用标记
fmt.Println("---- continue ---- ")
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
continue
}
}
// 使用标记
fmt.Println("---- continue label ----")
re:
for i := 1; i <= 3; i++ {
fmt.Printf("i: %d\n", i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf("i2: %d\n", i2)
continue re
}
}
}
以上实例执行结果为:
---- continue ----
i: 1
i2: 11
i2: 12
i2: 13
i: 2
i2: 11
i2: 12
i2: 13
i: 3
i2: 11
i2: 12
i2: 13
---- continue label ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11
Go 语言循环语句
Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。
goto 语法格式如下:
goto label;
..
.
label: statement;
goto 语句流程图如下:
在变量 a 等于 15 的时候跳过本次循环并回到循环的开始语句 LOOP 处:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 10
/* 循环 */
LOOP: for a < 20 {
if a == 15 {
/* 跳过迭代 */
a = a + 1
goto LOOP
}
fmt.Printf("a的值为 : %d\n", a)
a++
}
}
以上实例执行结果为:
a的值为 : 10
a的值为 : 11
a的值为 : 12
a的值为 : 13
a的值为 : 14
a的值为 : 16
a的值为 : 17
a的值为 : 18
a的值为 : 19
i := 1; i <= 3; i++ {
fmt.Printf(“i: %d\n”, i)
for i2 := 11; i2 <= 13; i2++ {
fmt.Printf(“i2: %d\n”, i2)
continue re
}
}
}
以上实例执行结果为:
---- continue ----
i: 1
i2: 11
i2: 12
i2: 13
i: 2
i2: 11
i2: 12
i2: 13
i: 3
i2: 11
i2: 12
i2: 13
---- continue label ----
i: 1
i2: 11
i: 2
i2: 11
i: 3
i2: 11
### Go 语言 goto 语句
[[外链图片转存中...(img-zFLQxvJX-1686120904270)]Go 语言循环语句](https://www.runoob.com/go/go-loops.html)
Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。
### 语法
goto 语法格式如下:
```go
goto label;
..
.
label: statement;
goto 语句流程图如下:
[外链图片转存中…(img-RYPuLDvm-1686120904271)]
在变量 a 等于 15 的时候跳过本次循环并回到循环的开始语句 LOOP 处:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 10
/* 循环 */
LOOP: for a < 20 {
if a == 15 {
/* 跳过迭代 */
a = a + 1
goto LOOP
}
fmt.Printf("a的值为 : %d\n", a)
a++
}
}
以上实例执行结果为:
a的值为 : 10
a的值为 : 11
a的值为 : 12
a的值为 : 13
a的值为 : 14
a的值为 : 16
a的值为 : 17
a的值为 : 18
a的值为 : 19