August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Go语言基础-流程控制
发布:2021年01月12日 | 作者:augustrush | 阅读量: 1031

Go里的流程控制方法主要有以下几种方式:

  • if - else条件语句

  • switch - case 选择语句

  • for - range 循环语句

  • goto 无条件跳转语句

  • defer 延迟执行

If - else 条件语句

Go里的条件语句模型是

if 条件1 {
    分支1
} else if 条件2 {
    分支2
} else {
    分支
}

Go编译器,对于{}的位置有严格的要求,它要求else ifelse和两边的花括号,必须在同一行。

由于Go是强类型, 所以要求你条件表达式必须严格返回布尔型的数据(nil01都不行)。

单分支判断

import "fmt"

func main() {
    age := 20
    if age > 18 {
        fmt.Println("已经成年了")
    } 
}

如果条件里需要满足多个条件,可以使用&&||

  • &&:表示且,左右都需要为true,最终结果才是true,否则为false

  • ||:表示或,左右只需要有一个为true, 最终结果即为true,否则为false

import "fmt"

func main() {
    age := 20
    gender := "male"
    if (age > 18 && gender == "male") {
        fmt.Println("是成年男性")
    }
}

多分支判断

if - else

import "fmt"

func main() {
    age := 20
    if age > 18 {
        fmt.Println("已经成年了")
    } else {
        fmt.Println("还未成年")
    }
}

if - else if - else

import "fmt"

func main() {
    age := 20
    if age > 18 {
        fmt.Println("已经成年了")
    } else if age >12 {
        fmt.Println("已经是青少年了")
    } else {
        fmt.Println("还不是青少年")
    }
}

高级写法

在if里可以允许先运行一个表达式,取得变量后,再对其进行判断,比如第一个例子里代码也可以写成这样

import "fmt"

func main() {
    if age := 20; age> 18 {
        fmt.Println("已经成年了")
    }
}

switch-case选择语句

Go里的选择语句模型是

switch 表达式 {
    case 表达式1:
        代码块
    case 表达式2:
        代码块
    case 表达式3:
        代码块
    case 表达式4:
        代码块
    default:
        代码块
}

拿switch后的表达式分别和case后的表达式进行对比,只要有一个case满足条件,就会执行对应的代码块,然后直接退出switch-case,如果一个都没有满足,才会执行default的代码块。

简单示例

import "fmt"

func main() {
    education := "本科"

    switch education {
    case "博士":
        fmt.Println("我是博士")
    case "研究生":
        fmt.Println("我是研究生")
    case "本科":
        fmt.Println("我是本科生")
    case "大专":
        fmt.Println("我是大专生")
    case "高中":
        fmt.Println("我是高中生")
    default:
        fmt.Println("学历未达标..")
    }
}

一个case多个条件

case后可以接多个条件,多个条件之间是的关系,用逗号隔开。

import "fmt"

func main() {
    month := 2

    switch month {
    case 3, 4, 5:
        fmt.Println("春天")
    case 6, 7, 8:
        fmt.Println("夏天")
    case 9, 10, 11:
        fmt.Println("秋天")
    case 12, 1, 2:
        fmt.Println("冬天")
    default:
        fmt.Println("输入有误...")
    }
}

case条件常量不能重复

当case后接的是常量时,该常量只能出现一次。

一下两种情况,在编译时,都会报错:duplicate case "male" in switch

错误案例一

gender := "male"

switch gender {
case "male":
    fmt.Println("男性")
      // 与上面重复
    case "male":
        fmt.Println("男性")
    case "female":
        fmt.Println("女性")
}

错误案例二

gender := "male"

switch gender {
    case "male", "male":
        fmt.Println("男性")
    case "female":
        fmt.Println("女性")
}

switch后可接函数

switch后面可以接一个函数,只要保证case后的值类型与函数的返回值一致即可。

import "fmt"

// 判断一个同学是否有挂科记录的函数
// 返回值是布尔类型
func getResult(args ...int) bool {
    for _, i := range args {
        if i < 60 {
            return false
        }
    }
    return true
}

func main() {
    chinese := 80
    english := 50
    math := 100

    switch getResult(chinese, english, math) {
    // case 后也必须 是布尔类型
    case true:
        fmt.Println("该同学所有成绩都合格")
    case false:
        fmt.Println("该同学有挂科记录")
    }
}

switch可不接表达式

switch后可以不接任何变量、表达式、函数。

当不接任何东西时,switch-case就相当于if-else if-else

score := 30

switch {
    case score >= 95 && score <= 100:
        fmt.Println("优秀")
    case score >= 80:
        fmt.Println("良好")
    case score >= 60:
        fmt.Println("合格")
    case score >= 0:
        fmt.Println("不合格")
    default:
        fmt.Println("输入有误...")
}

switch的穿透能力

正常情况下switch-case的执行顺序是:只要有一个case满足条件,就会直接退出switch-case,如果一个都没有满足,才会执行default的代码块。

但是有一种情况是例外。

那就是当case使用关键字fallthrough开启穿透能力的时候。

s := "hello"
switch {
case s == "hello":
    fmt.Println("hello")
    fallthrough
case s != "world":
    fmt.Println("world")
}

代码输出结果:

hello

world

需要注意的是,fallthrough只能穿透一层,意思是它让你直接执行下个case的语句,而且不需要判断条件。

s := "hello"
switch {
case s == "hello":
    fmt.Println("hello")
    fallthrough
case s == "xxxx":
    fmt.Println("xxxx")
case s != "world":
    fmt.Println("world")
}

输出如下,并不会输出最后一个case的结果(即使它符合条件)

hello

xxxx

for-range 循环语句

for 循环的基本模型:

for [condition | (init; condition; increment) | Range]
{
    statement(s);
}

for后面可以接三种类型的表达式:

  1. 接一个条件表达式 (类似Python的where)

  2. 接三个表达式

  3. 接一个range表达式

但还有第四种-->不接受表达式

接一个条件表达式

a := 1
for a <= 5 {
    fmt.Println(a)
    a++
}

接三个表达式

for 后面,紧接着三个表达式,使用;分割。

这三个表达式,各有各的用途

  • 第一个表达式: 初始化控制变量,在整个循环生命周期内,只运行一次;

  • 第二个表达式: 设置循环控制条件,当返回true,继续循环,返回false,结束循环;

  • 第三个表达式: 每次循环开始(除第一次)时,给控制变量递增或递减。

import "fmt"

func main() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i)
    }
}

不接受表达式:无限循环

在Go中,没有while循环,如果要实现无限循环,也可以完全使用for来实现。

当你不加任何的判断条件时,就相当于你每次的判断都为true,程序就会一直处于运行状态,但是一般我们并不会让程序处于死循环,在满足一定的条件下,可以使用关键字break退出循环体,也可以使用continue直接跳到下一个循环。

for {
    代码块
}
// 等价于
for ;; {
    代码块
}

举个栗子:

import "fmt"

func main() {
    var i int = 1
    for {
        if i > 5 {
            break
        }
        fmt.Printf("hello, %d\n", i)
        i++
    }
}

接for-range语句

遍历一个可迭代对象,是一个很常用的操作。在Go可以使用for-range的方式来实现。

range后可接数组、切片,字符串等

由于range会返回两个值:索引和数据,若你后面的代码用不到索引,需要使用_接收。

import "fmt"

func main() {
    myarr := [...]string{"world", "python", "go"}
    for _, item := range myarr {
        fmt.Printf("hello, %s\n", item)
    }
}

如果你用一个变量来接收的话,接收到的是索引

import "fmt"

func main() {
    myarr := [...]string{"world", "python", "go"}
    for i := range myarr {
        fmt.Printf("hello, %v\n", i)
    }
}

goto 无条件跳转语句

goto顾名思义,是跳转的意思。

goto后接一个标签,这个标签的意义是告诉Go程序下一步要执行哪里的代码。

所以这个标签如何放置,放置在哪里,是goto里最需要注意的。

goto 标签;
...
...
标签: 表达式;

示例

goto 可以打破原有代码执行顺序,直接跳转到某一行执行代码。

import "fmt"

func main() {
    goto flag
    fmt.Println("B")
flag:
    fmt.Println("A")
}

执行结果

A

并不会输出B,而只会输出A

如何使用?

goto语句通常与条件语句配合使用。可用来实现条件转移,构成循环,跳出循环体等功能。

举个栗子:

// 实现一个打印1到5的循环
import "fmt"

func main() {
    i := 1
flag:
    if i <= 5 {
        fmt.Println(i)
        i++
        goto flag
    }
}

使用goto实现continue的效果

// 打印1到10的所有偶数
import "fmt"

func main() {
    i := 1
flag:
    for i <= 10 {
        if i%2 == 1 {
            i++
            goto flag
        }
        fmt.Println(i)
        i++
    }
}

注意事项

goto语句与标签之间不能有变量声明,否则编译错误。

import "fmt"

func main() {
    fmt.Println("start")
    goto flag
    var say = "hello oldboy"
    fmt.Println(say)
flag:
    fmt.Println("end")
}

编译错误

.\main.go:7:7: goto flag jumps over declaration of say at .\main.go:8:6



  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed