10《Go语言入门》循环和条件
重要知识点:
- Go仅支持循环关键字for,没有while循环关键字。
- 条件表达式的结果必须为布尔值。
- switch条件表达式不仅支持常量和整数,而且和JS一样支持字符串。
- switch不需要break来明确退出一个case。
- 不设定switch后的条件表达式,能实现if else的效果。
- 不支持三目(元)运算符。
⚡️这是我纯手写的《Go语言入门》,源码+文章,手把手教你入门Go。看了你就会!
⚡️文章中所有的代码我都放到了 github.com/GanZhiXiong/go_learning 这个仓库中!
⚡️看文章时,对照仓库中代码学习效果更佳哦!
循环
for循环
Go仅支持循环关键字for
下面为for循环常用的写法,注意Go中for循环是不用写括号的,写了括号则会报错。
1 | for i := 0; i<5; i++ |
当然还有其他写法,如:
1 | func TestLoop(t *testing.T) { |
while循环
上面已经说过了Go仅支持循环关键字for,
所以也就没有while关键字了,那么while循环怎么写呢?
while条件循环
其他编程语言的while条件循环是这么写的:
1 | while (n < 5) { |
其实Go的while条件循环只是用for替代while,然后省略了括号而已。
1 | for n < 5 { |
while无限循环
其他编程语言的while无限循环是这么写的:
1 | while (true) { |
那么Go的无限循环也只是将while换成了for,然后省略了括号和括号内的代码而已。
1 | for { |
示例
1 | func TestWhileLoop(t *testing.T) { |
条件
if条件
Go中也有if
、else
、else if
。
和其他语言的区别如下:
不用将条件括号起来,如果加了括号,则会提示警告
Unwrap parentheses
。10_condition_test.go 1
2
3
4
5
6
7
8
9
10
11func TestIf(t *testing.T) {
n := -1
//var n int
if n < 0 {
t.Log(n, "为负数")
} else if n == 0 {
t.Log(n, "为0")
} else {
t.Log(n, "为正数")
}
}条件表达式的结果必须为布尔值。
例如JavaScript的条件表达式的结果不一定要是布尔值,如:
1
2
3if(1) {
console.log("1")
}而Go则会报错,如:
1
2
3
4// Non-bool '1' (type untyped int) used as condition
if 1 {
}
switch条件
Go的switch和其他编程语言有如下区别:
条件表达式不限制为常量或整数,而且和JS一样支持字符串。
10_condition_test.go 1
2
3
4
5
6
7
8
9
10func TestSwitch(t *testing.T) {
switch os := runtime.GOOS; os {
case "darwin":
t.Log("macOS")
case "linux":
t.Log("Linux")
default:
t.Logf("%s", os)
}
}单个case中,可以出现多个结果选项,使用逗号分隔。
10_condition_test.go 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30func TestGetGrade(t *testing.T) {
/* 定义局部变量 */
var grade string
var marks int = 50
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)
}不需要break来明确退出一个case
通过上面的代码,我们可以看到Go的switch不需要写break的,像其他的编程语言则不行。
比如JavaScript,不加break,则会执行后面的case,直到break为止。可以不设定switch之后的条件表达式,整个switch结构与多个if…else…的逻辑作用等同,例如:
10_loop_test.go 1
2
3
4
5
6
7
8
9
10
11func TestSwitchIfElse(t *testing.T) {
n := 5
switch {
case n >= 0 && n <= 3:
t.Log("0-3")
case n >= 4 && n <=6:
t.Log("4-6")
case n >= 7 && n <= 9:
t.Log("7-9")
}
}
条件表达式支持变量赋值
即if或switch表达式之前添加一个执行语句,再根据变量值进行判断,这是if和switch的特殊写法。
1 | if var declaration; condition { |
例如:
1 | if err := Connect(); err != nil { |
Connect 是一个带有返回值的函数,err:=Connect() 是一个语句,执行 Connect 后,将错误保存到 err 变量中。
err != nil 才是 if 的判断表达式,当 err 不为空时,打印错误并返回。
这种写法可以将返回值与判断放在一行进行处理,而且返回值的作用范围被限制在 if、else 语句组合中。
再例如:
1 | func TestIfMultiSec(t *testing.T) { |
再例如:
1 | func TestSwitch(t *testing.T) { |
在编程中,变量的作用范围越小,所造成的问题可能性越小,每一个变量代表一个状态,有状态的地方,状态就会被修改,函数的局部变量只会影响一个函数的执行,但全局变量可能会影响所有代码的执行状态,因此限制变量的作用范围对代码的稳定性有很大的帮助。
不支持三目运算符
三目(元)运算符广泛存在于其他语言中,比如:
python:
1 | val = trueValue if expr else falseValue |
javascript:
1 | const val = expr ? trueValue : falseValue |
c、c++:
1 | const char *val = expr ? "trueValue" : "falseValue"; |
然而,被广泛支持的三目运算符在golang中却是不存在的!如果我们写出类似下面的代码:
1 | val := expr ? "trueValue" : "falseValue" |
则编译器会报错。
Go的作者认为三元表达式会让让开发者写出复杂且难以理解的表达式,虽然if-else看上去代码量更多,但是也会阅读起来会更加清晰,而在Go作者看来一种编程语言只需要一种条件控制结构,因此抛弃了三元运算符。
10《Go语言入门》循环和条件