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++

当然还有其他写法,如:

10_loop_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func TestLoop(t *testing.T) {
t.Log("你可以这样写")
i := 0
for ; i < 5; i++ {
t.Log(i)
}

t.Log("也可以这写")
for i = 1 ; i < 5; i++ {
t.Log(i)
}

t.Log("也可以这写")
for i := 0; i < 5; i++ {
t.Log(i)
}
}

while循环

上面已经说过了Go仅支持循环关键字for
所以也就没有while关键字了,那么while循环怎么写呢?

while条件循环

其他编程语言的while条件循环是这么写的:

1
2
3
while (n < 5) {
...
}

其实Go的while条件循环只是用for替代while,然后省略了括号而已。

1
2
3
for n < 5 {
...
}

while无限循环

其他编程语言的while无限循环是这么写的:

1
2
3
while (true) {
...
}

那么Go的无限循环也只是将while换成了for,然后省略了括号和括号内的代码而已。

1
2
3
for {
...
}

示例

10_loop_test.go
1
2
3
4
5
6
7
8
9
10
11
12
func TestWhileLoop(t *testing.T) {
n := 0
for n < 5 {
t.Log(n)
n++
}

for {
t.Log(n)
n++
}
}

条件

if条件

Go中也有ifelseelse if
和其他语言的区别如下:

  • 不用将条件括号起来,如果加了括号,则会提示警告Unwrap parentheses

    10_condition_test.go
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    func 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
    3
    if(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
    10
    func 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
    30
    func 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
    11
    func 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
2
3
if var declaration; condition {
...
}

例如:

1
2
3
4
if err := Connect(); err != nil {
fmt.Println(err)
return
}

Connect 是一个带有返回值的函数,err:=Connect() 是一个语句,执行 Connect 后,将错误保存到 err 变量中。
err != nil 才是 if 的判断表达式,当 err 不为空时,打印错误并返回。

这种写法可以将返回值与判断放在一行进行处理,而且返回值的作用范围被限制在 if、else 语句组合中。

再例如:

10_loop_test.go
1
2
3
4
5
6
7
8
9
10
11
12
func TestIfMultiSec(t *testing.T) {
if a := 1 == 1; a {
t.Log("1 == 1")
}

// 在后面我们回经常用到变量赋值的条件表达式,下例就是用到了Go的函数多返回值
//if v, err := Fun(); err == nil {
//
//} else {
//
//}
}

再例如:

1
2
3
4
5
6
7
8
9
10
func TestSwitch(t *testing.T) {
switch os := runtime.GOOS; os {
case "darwin":
t.Log("macOS")
case "linux":
t.Log("Linux")
default:
t.Logf("%s", os)
}
}

在编程中,变量的作用范围越小,所造成的问题可能性越小,每一个变量代表一个状态,有状态的地方,状态就会被修改,函数的局部变量只会影响一个函数的执行,但全局变量可能会影响所有代码的执行状态,因此限制变量的作用范围对代码的稳定性有很大的帮助。

不支持三目运算符

三目(元)运算符广泛存在于其他语言中,比如:
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语言入门》循环和条件

https://ganzhixiong.com/p/204165a4/

Author

干志雄

Posted on

2021-01-12

Updated on

2021-01-12

Licensed under

Comments