当前位置:网站首页>go语言慢速入门——流程控制语句
go语言慢速入门——流程控制语句
2022-07-30 21:09:00 【zy010101】
流程控制语句
go的流程控制语句很有特色。if-else,for,switch-case。注意go没有while和do-while语句。除此之外go还有和特定类型绑定的流程控制模块。例如,用于容器类型的for-range循环。
go支持break,continue以及goto语句,另外go还支持特有的fallthrough语句。
if-else语句
go语言中的if-else语句格式如下:
if InitSimpleStatement; Condition {
// do something
} else {
// do something
}
需要对一下几点进行说明。
- InitSimpleStatement部分是可选的,如果它没被省略掉,则它必须为一条简单语句。 如果它被省略掉,它可以被视为一条空语句(简单语句的一种)。
- Condition必须为一个结果为布尔值的表达式
- 关键字 if 和 else 之后的左大括号 { 必须和关键字在同一行,如果你使用了 else-if 结构,则前段代码块的右大括号 } 必须和 else-if 关键字在同一行。这两条规则都是被编译器强制规定的。
所以下面这种在其它语言中经常写的方式在go语言中是错误的。
const a = 10
if a{
// condition的结果必须是布尔值。
} else {
}
简单语句类型列表
Go中有六种简单语句类型:
- 变量短声明语句。
- 纯赋值语句,包括x += y这种运算形式。
- 有返回结果的函数或方法调用,以及通道的接收数据操作。
- 通道的发送数据操作。
- 空语句。
- 自增(x++)和自减(x–)语句。
和其它语言类似,if-else语句可以后跟多个else-if来,例如:
if x{
// condition的结果必须是布尔值。
//do
} else if y{
//do
}else{
//do
}
for循环
在go语言中,for循环形式如下所示:
for InitSimpleStatement; Condition; PostSimpleStatement {
// do something
}
go中没有while和do-while,循环只能使用for来解决。因此,它具备以下几个特点。
- InitSimpleStatement(初始化语句)和PostSimpleStatement(步尾语句)两个部分必须均为简单语句,并且PostSimpleStatement不能为一个变量短声明语句。
- Condition必须为一个结果为布尔值的表达式(它被称为条件表达式)。
- 所有这三个刚提到的部分都是可选的
- 在一个for循环流程控制中,如果InitSimpleStatement和PostSimpleStatement两部分同时被省略(可将它们视为空语句),则和它们相邻的两个分号也可被省略。这时候,和其它语言中的while循环看起来就一样了。
- 在一个for循环流程控制中,如果条件表达式部分被省略,则编译器视其为true。
- 每个for流程控制包括至少两个子代码块。 其中一个是隐式的,另一个是显式的(花括号起始和终止的部分,又称循环体)。 此显式代码块内嵌在隐式代码块之中。
下面的代码是等价的。
for ; true; {
}
for true {
}
for ; ; {
}
for {
}
比如下面的代码打印出012,而不是0。
for i := 0; i < 3; i++ {
fmt.Print(i)
i := i // 这里声明的变量i遮挡了上面声明的i。
// 右边的i为上面声明的循环变量i。
i = 10 // 新声明的i被更改了。
_ = i
}
break语句
break语句可以用来提前跳出包含此break语句的最内层for循环。
break可以使用在一个switch-case流程控制的任何分支代码块之中以提前跳出此switch-case流程控制。
continue语句
continue语句可以被用来提前结束包含此continue语句的最内层for循环的当前循环步。
switch-case语句
go中的switch-case语句完整形式如下:
switch InitSimpleStatement; CompareOperand0 {
case CompareOperandList1:
// do something
case CompareOperandList2:
// do something
...
case CompareOperandListN:
// do something
default:
// do something
}
- InitSimpleStatement部分必须为一条简单语句,它是可选的。
- CompareOperand0部分必须为一个表达式(如果它没被省略的话,见下)。 此表达式的估值结果总是被视为一个类型确定值。如果它是一个类型不确定值,则它被视为类型为它的默认类型的类型确定值。 因为这个原因,此表达式不能为类型不确定的nil值。 CompareOperand0常被称为switch表达式。
- 每个CompareOperandListX部分(X表示1到N)必须为一个用(英文)逗号分隔开来的表达式列表。 其中每个表达式都必须能和CompareOperand0表达式进行比较。 每个这样的表达式常被称为case表达式。 如果其中case表达式是一个类型不确定值,则它必须能够自动隐式转化为对应的switch表达式的类型,否则编译将失败。
- 每个case CompareOperandListX:部分和default:之后形成了一个隐式代码块。 每个这样的隐式代码块和它对应的case CompareOperandListX:或者default:形成了一个分支。 每个分支都是可选的。
一个switch-case流程控制的例子:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
switch n := rand.Intn(100); n%9 {
case 0:
fmt.Println(n, "is a multiple of 9.")
// 和很多其它语言不一样,程序不会自动从一个
// 分支代码块跳到下一个分支代码块去执行。
// 所以,这里不需要一个break语句。
case 1, 2, 3:
fmt.Println(n, "mod 9 is 1, 2 or 3.")
break // 这里的break语句可有可无的,效果
// 是一样的。执行不会跳到下一个分支。
case 4, 5, 6:
fmt.Println(n, "mod 9 is 4, 5 or 6.")
// case 6, 7, 8:
// 上一行可能编译不过,因为6和上一个case中的
// 6重复了。是否能编译通过取决于具体编译器实现。
default:
fmt.Println(n, "mod 9 is 7 or 8.")
}
}
如果你想要C/C++中switch语句在不使用break语句的情况下的效果,可以使用fallthrough语句来实现。
- 一条fallthrough语句必须为一个分支代码块中的最后一条语句。
- 一条fallthrough语句不能出现在一个switch-case流程控制中的最后一个分支代码块中。
比如,下面代码的几个fallthrough使用是不合法的。
switch n := rand.Intn(100) % 5; n {
case 0, 1, 2, 3, 4:
fmt.Println("n =", n)
// 此整个if代码块为当前分支中的最后一条语句
if true {
fallthrough // error: 不是当前分支中的最后一条语句
}
case 5, 6, 7, 8:
n := 99
fallthrough // error: 不是当前分支中的最后一条语句
_ = n
default:
fmt.Println(n)
fallthrough // error: 不能出现在最后一个分支中
}
一个switch-case流程控制中的InitSimpleStatement语句和CompareOperand0表达式都是可选的。 如果CompareOperand0表达式被省略,则它被认为类型为bool类型的true值。 如果InitSimpleStatement语句被省略,其后的分号也可一并被省略。
参考资料
https://gfw.go101.org/article/control-flows.html
https://learnku.com/docs/the-way-to-go/chapter-description/3591
边栏推荐
猜你喜欢
随机推荐
JS中获取元素属性的8大方法
[Limited Time Bonus] 21-Day Learning Challenge - MySQL from entry to mastery
How strict Typescript strict mode?
DPW-SDNet: Dual Pixel-Wavelet Domain Deep CNNsfor Soft Decoding of JPEG-Compressed Images
Oracle ADG状态查看与相关视图
弹性盒子模型
(7/29) Basic board minimum spanning tree prim+kruskal
2021年PHP-Laravel面试题问卷题 答案记录
MySQL的on duplicate key update 的使用
用于命名实体识别的模块化交互网络
Flink_CDC搭建及简单使用
这本记述40年前历史的游戏书,预言的却是当下的事
The structure of knowledge in the corners of the C language
MySql 创建索引
文字的选择与排版
C语言犄角旮旯的知识之结构体
2022-07-29 mysql/stonedb慢SQL-Q17-分析
【机器学习】梯度下降背后的数学之美
关于MySQL主从复制的数据同步延迟问题
@RequestParam使用