Go语言自学十八式:流程控制篇

Go里的流程控制方法有如下这么多种:

  • if - else 条件语句

  • switch - case 选择语句

  • for - range 循环语句

  • goto 无条件跳转语句

  • defer 延迟执行

if-else​ 条件语句

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

Go编译器严格要求else if (或 else)和 两边的花括号({ 和 } ),必须在同一行。

由于 Go是 强类型,要求条件表达式必须严格返回布尔型的数据(nil 、 0 和 1 都不行)

单分支判断

只有一个 if ,没有 else

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 选择语句

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

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

示例

switch 后接一个你要判断变量 education (学历),然后 case 会拿这个 变量去和它后面的表达式(可能是常量、变量、表达式等)进行判等。

如果相等,就执行相应的代码块。如果不相等,就接着下一个 case。

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")
}

输出如下,并不会输出 world(即使它符合条件):
hello
xxxx

 for 循环语句

 for 循环格式:

for [condition |  ( init; condition; increment ) | Range | 不接表达式]
{
   statement(s);
}

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

  1. 接一个条件表达式

  2. 接三个表达式

  3. 接一个 range 表达式

  4. 不接表达式

接一个条件表达式

这个例子会打印 1 到 5 的数值。

import "fmt"

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

输出如下:
1
2
3
4
5

接三个表达式

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

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

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

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

这边的例子和上面的例子,是等价的。

import "fmt"

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

输出如下:
1
2
3
4
5

不接表达式:无限循环

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

输出如下:
hello, 1
hello, 2
hello, 3
hello, 4
hello, 5

接 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)
    }
}

输出如下:
hello, world
hello, python
hello, go

goto

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

goto 后接一个下一步要执行哪里的代码的标签,模型如下:

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

示例

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

import "fmt"

func main() {

    goto flag
    fmt.Println("B")
flag:
    fmt.Println("A")

}

输出如下:
执行结果,并不会输出 B ,而只会输出 A

如何使用

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

举个栗子,用 goto 的方式来实现一个打印 1到5 的循环。

import "fmt"

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

输出如下:
1
2
3
4
5

举个栗子,使用 goto 实现 类型 break 的效果。

import "fmt"

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

输出如下

1
2
3
4
5

再举个栗子,使用 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++
    }
}

输出如下

2
4
6
8
10

注意事项

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值