如何在 Go 中编写 Switch 语句

目录

  1. 在 Go 中导入包
  2. 理解 Go 中包的可见性
  3. 如何在 Go 中编写条件语句
  4. 如何在 Go 中编写 Switch 语句
  5. 如何在 Go 中构造 for 循环
  6. 在循环中使用 Break 和 Continue
  7. 如何在 Go 中定义并调用函数
  8. 如何在 Go 中使用可变参数函数
  9. 了解 Go 中的 defer
  10. 了解 Go 中的 init
  11. 用构建标签定制 Go 二进制文件
  12. 了解 Go 中的指针
  13. 在 Go 中定义结构体
  14. 在 Go 中定义方法
  15. 如何构建和安装 Go 程序
  16. 如何在 Go 中使用结构体标签
  17. 如何在 Go 使用 interface
  18. 在不同的操作系统和架构编译 Go 应用
  19. 用 ldflags 设置 Go 应用程序的版本信息
  20. 在 Go 里面如何使用 Flag 包

介绍

[条件语句]({{< relref "/docs/23-How_To_Write_Conditional_Statements_in_Go.md" >}})使程序员有能力指导他们的程序在某个条件为真时采取某些行动,在条件为假时采取另一种行动。经常,我们想把一些变量与多个可能的值进行比较,在每种情况下采取不同的行动。仅仅使用if语句就可以做到这一点。然而,编写软件不仅是为了让事情顺利进行,也是为了向未来的自己和其他开发者传达你的意图。switch是一个替代性的条件语句,对于传达你的 Go 程序在遇到不同选项时采取的行动很有用。

我们可以用 switch 语句编写的所有内容也可以用if语句编写。在本教程中,我们将看几个例子,看看 switch 语句能做什么,它所取代的if语句,以及它最合适的应用场合。

Switch 语句的结构

Switch 通常用于描述当一个变量被分配到特定值时程序所采取的行动。下面的例子演示了我们如何使用 if 语句来完成这个任务。

package main

import "fmt"

func main() { flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}

 for _, flav := range flavors {  if flav == "strawberry" {   fmt.Println(flav, "is my favorite!")   continue  }

  if flav == "vanilla" {   fmt.Println(flav, "is great!")   continue  }

  if flav == "chocolate" {   fmt.Println(flav, "is great!")   continue  }

  fmt.Println("I've never tried", flav, "before") }}

这将输出如下信息:

chocolate is great!
vanilla is great!
strawberry is my favorite!
I've never tried banana before

main中,我们定义了一个slice的冰激凌口味。然后我们使用一个[for loop]({{< relref "/docs/25-How_To_Construct_For_Loops_in_Go.md" >}})来迭代它们。我们使用三个if语句来打印不同的信息,表明对不同冰淇淋口味的偏好。每个if语句必须使用continue语句来停止for循环的执行,这样就不会在最后打印出首选冰淇淋口味的默认信息。

当我们添加新的偏好时,我们必须不断添加if语句来处理新的情况。重复的信息,如 "香草"和 "巧克力"的情况,必须有重复的if语句。对于我们代码的未来读者(包括我们自己)来说,if语句的重复性掩盖了它们所做的重要部分--将变量与多个值进行比较并采取不同的行动。另外,我们的回退信息与条件语句分开,使得它看起来不相关。转换器 "语句可以帮助我们更好地组织这个逻辑。

switch 语句以 switch 关键字开始,在其最基本的形式下,后面是一些要进行比较的变量。之后是一对大括号({}),其中可以出现多个case 子句。case 子句描述了当提供给 switch 语句的变量等于 case 子句所引用的值时,Go 程序应该采取的行动。下面的例子将先前的例子转换为使用一个switch而不是多个if语句:

package main

import "fmt"

func main() { flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}

 for _, flav := range flavors {  switch flav {  case "strawberry":   fmt.Println(flav, "is my favorite!")  case "vanilla", "chocolate":   fmt.Println(flav, "is great!")  default:   fmt.Println("I've never tried", flav, "before")  } }}

输出与之前相同:

chocolate is great!
vanilla is great!
strawberry is my favorite!
I've never tried banana before

我们再次在main中定义了一片冰淇淋的口味,并使用range语句来遍历每个口味。但是这一次,我们使用了一个switch语句来检查flav变量。我们使用两个case'子句来表示偏好。我们不再需要继续'语句,因为只有一个case子句将被switch语句执行。我们还可以将"巧克力"和 "香草"条件的重复逻辑结合起来,在 case子句的声明中用逗号将其分开。default子句是我们的万能子句。它将对我们在 switch 语句中没有考虑到的任何口味运行。在这种情况下,"香蕉"将导致 default 的执行,打印出 "I've never tried banana before"的信息。

这种简化形式的switch语句解决了它们最常见的用途:将一个变量与多个替代品进行比较。它还为我们提供了便利,当我们想对多个不同的值采取相同的行动,以及在没有满足所列的条件时,通过使用所提供的default关键字采取一些其他行动。

当这种简化的switch形式被证明太有局限性时,我们可以使用一种更通用的switch语句形式。

通常的 Switch 语句

switch语句对于将更复杂的条件集合在一起以显示它们之间有某种联系是很有用的。这在将某些变量与一定范围的值进行比较时最常用,而不是像前面的例子中的特定值。下面的例子使用if语句实现了一个猜谜游戏,可以从switch语句中受益:

package main

import ( "fmt" "math/rand" "time")

func main() { rand.Seed(time.Now().UnixNano()) target := rand.Intn(100)

 for {  var guess int  fmt.Print("Enter a guess: ")  _, err := fmt.Scanf("%d", &guess)  if err != nil {   fmt.Println("Invalid guess: err:", err)   continue  }

  if guess > target {   fmt.Println("Too high!")   continue  }

  if guess < target {   fmt.Println("Too low!")   continue  }

  fmt.Println("You win!")  break }}

输出将取决于所选择的随机数和你玩游戏的程度。下面是一个例子会话的输出:

Enter a guess: 10
Too low!
Enter a guess: 15
Too low!
Enter a guess: 18
Too high!
Enter a guess: 17
You win!

我们的猜谜游戏需要一个随机数来比较猜测的结果,所以我们使用math/rand包中的rand.Intn函数。为了确保我们每次玩游戏都能得到不同的target值,我们使用rand.Seed来根据当前时间随机化随机数发生器。rand.Intn的参数100将给我们一个0-100范围内的数字。然后我们使用for循环来开始收集玩家的猜测。

fmt.Scanf函数为我们提供了一种方法来读取用户的输入到我们选择的变量中。它接受一个格式化的字符串动词,将用户的输入转换为我们期望的类型。这里的%d意味着我们期望一个 int,我们传递 guess 变量的地址,这样 fmt.Scanf 就能够设置该变量。在[处理任何解析错误]({{< relref "/docs/17-Handling_Errors_in_Go_DigitalOcean.md" >}})之后,我们使用两个if语句来比较用户的猜测和target值。它们返回的stringbool一起控制显示给玩家的信息,以及游戏是否会退出。

这些 if 语句掩盖了一个事实,即变量被比较的数值范围都有某种联系。一眼就能看出我们是否遗漏了该范围的某些部分,这也是很困难的。下一个例子重构了前面的例子,用switch语句代替:

package main

import ( "fmt" "math/rand")

func main() { target := rand.Intn(100)

 for {  var guess int  fmt.Print("Enter a guess: ")  _, err := fmt.Scanf("%d", &guess)  if err != nil {   fmt.Println("Invalid guess: err:", err)   continue  }

  switch {  case guess > target:   fmt.Println("Too high!")  case guess < target:   fmt.Println("Too low!")  default:   fmt.Println("You win!")   return  } }}

这将产生类似以下的输出:

Enter a guess: 25
Too low!
Enter a guess: 28
Too high!
Enter a guess: 27
You win!

在这个版本的猜谜游戏中,我们用一个switch语句代替了if语句块。我们省略了switch的表达式参数,因为我们只对使用switch来收集条件语句感兴趣。每个case子句包含一个不同的表达式,将guesstarget进行比较。与第一次用switch代替if语句类似,我们不再需要continue语句,因为只有一个case子句会被执行。最后,default子句处理guess == target的情况,因为我们已经用另外两个case子句覆盖了所有其他可能的值。

在我们目前看到的例子中,正好有一个 case 语句将被执行。偶尔,你可能希望结合多个case子句的行为。switch语句提供了另一个实现这种行为的关键字。

Fallthrough

有时你想重复使用另一个 case 子句包含的代码。在这种情况下,可以使用 fallthrough 关键字要求 Go 运行下一个 case 子句的主体。下面这个例子修改了我们之前的冰淇淋口味的例子,以更准确地反映我们对草莓冰淇淋的热情:

package main

import "fmt"

func main() { flavors := []string{"chocolate", "vanilla", "strawberry", "banana"}

 for _, flav := range flavors {  switch flav {  case "strawberry":   fmt.Println(flav, "is my favorite!")   fallthrough  case "vanilla", "chocolate":   fmt.Println(flav, "is great!")  default:   fmt.Println("I've never tried", flav, "before")  } }}

将得到如下输出:

chocolate is great!
vanilla is great!
strawberry is my favorite!
strawberry is great!
I've never tried banana before

正如我们之前看到的,我们定义了一个 string 片段来表示口味,并使用 for 循环来迭代。这里的 switch 语句与我们之前看到的语句相同,但是在 case 子句的末尾添加了 fallthrough 关键字,即 strawberry。这将使 Go 运行case "strawberry":的主体,首先打印出字符串strawberry is my favorite!。当它遇到fallthrough时,它将运行下一个case子句的主体。这将导致case "vanilla", "chocolate":的主体运行,打印出strawberry is great!

Go 开发人员不经常使用fallthrough关键字。通常情况下,通过使用fallthrough实现的代码重用,可以通过定义一个具有公共代码的函数来更好地获得。由于这些原因,一般不鼓励使用fallthrough

总结

switch语句帮助我们向阅读代码的其他开发者传达出彼此有某种联系。使我们在将来添加新的情况时更容易添加不同的行为,并有可能确保任何忘记的事情也能通过default子句得到正确处理。下次你发现自己写的多个if语句都涉及同一个变量时,试着用switch语句重写它--你会发现当需要考虑其他值时,它将更容易重写。

如果你想了解更多关于 Go 编程语言的信息,请查看整个How To Code in Go 系列


本文由 mdnice 多平台发布

如何在 Go 中编写 Switch 语句相关推荐

  1. 如何在Ruby中编写switch语句

    如何在Ruby中编写switch语句? #1楼 案例...当 在Chuck的答案中添加更多示例: 带参数: case a when 1puts "Single value" whe ...

  2. 「每周译Go」如何在 Go 中编写 Switch 语句

    目录 在 Go 中导入包 理解 Go 中包的可见性 如何在 Go 中编写条件语句 如何在 Go 中编写 Switch 语句 如何在 Go 中构造 for 循环 在循环中使用 Break 和 Conti ...

  3. python中while语句是_如何在Python中使用while语句[适合初学者]

    while语句是重复循环的语句,那么如何用Python编写,下面Gxl网就带领大家来学习一下Python中使用while语句.[推荐阅读:Python视频教程] 一:什么是while语句?Python ...

  4. C#中的Switch语句【C#】

    C#中的Switch语句 题目描述 编写一个控制台应用,实现以下功能:根据输入的字符,输出通过.不通过和输入成绩无效. (1)无论输入A.B.C.D,都输出通过: (2)输入E,则输出不通过: (3) ...

  5. c语言switch斐波那契,在斐波那契数列中使用switch语句

    我正在编写一个程序,它使用递归计算给定整数的斐波那契数.我创建了自己的函数'fibonacci',并让程序在循环中运行,如代码中所示.在斐波那契数列中使用switch语句 该程序要我使用switch语 ...

  6. linux命令行运行c程序,如何在Linux中编写和运行C程序

    Linux正在成为开发人员的编程天堂,成为开源和免费操作系统. Turbo C编译器已经是一种编译程序的旧方法,所以让程序员转向Linux以获得新的编程环境. 在本文中,我们将解释如何编写,编译和运行 ...

  7. 如何在Go中编写多行字符串?

    本文翻译自:How do you write multiline strings in Go? Does Go have anything similar to Python's multiline ...

  8. 如何在Go中编写防弹代码:不会失败的服务器工作流程

    by Tal Kol 通过塔尔科尔 如何在Go中编写防弹代码:不会失败的服务器工作流程 (How to write bulletproof code in Go: a workflow for ser ...

  9. [转载] Python中的switch语句的替代品

    参考链接: Java中的switch语句 Python 中没有 switch语句. 一般用if-else 语句可以替代switch语句,今天学习了使用字典的映射来代替switch语句.Mark一下 d ...

最新文章

  1. 机器学习入门学习笔记:(3.2)ID3决策树程序实现
  2. 网狐框架分析八--web登录游戏大厅流程
  3. react使用link跳转传递参数_React-Typescript之路由跳转(使用this.props.history.push)
  4. 安卓流行布局开源库_如何使用流行度在开源库之间进行选择
  5. 电子琴仿真c语言程序,矩阵键盘模拟电子琴C语言程序设计
  6. linux命令怎么查看文件时间排序,linux中ls命令按照文件大小排...-ls命令按大小与时间排序文件...-ls按时间排序输出文件列表的实例分析_169IT.COM...
  7. (转)OL记载Arcgis Server切片
  8. ETL工具-Taskctl在Windows作业类型的使用(Soap服务驱动)
  9. python linux 上 RS485通信 Modbus协议
  10. Android 开发框架xUtils3
  11. OSI七层网络协议归纳
  12. 克罗内克张量积 Kron 的 OpenCV C++实现
  13. 工程师高级职称计算机考试成绩查询,高级工程师职称查询
  14. Day3:MVP+ButterKnife+Dagger2的使用
  15. 关于RSA共模攻击e1,e2不互素的解法
  16. get the sack
  17. c 数组上限_深度文章,高手必看:C编程表驱动法编程实践(精华帖,建议收藏并实践)...
  18. JavaScript 实现 HTMLDecode
  19. 青岛智能物联网产才融合中心成立,山东大学携手百度飞桨海尔海纳云等共育AI人才...
  20. SEO具体是怎么优化的?

热门文章

  1. java heap最大最小参数_闲谈JVM(一):浅析JVM Heap参数配置
  2. 用计算机弹歌说散就散,2018开年最红的4首歌:等你下课垫底,说散就散第2,第1火遍全网...
  3. 如何选择导电滑环材料
  4. 【总结】一些简单线段树题目的口胡题解
  5. Selenium自动化测试:8种元素定位+unittest框架设计
  6. 计算机网络 拥塞控制和流量控制,简述TCP的流量控制与拥塞控制
  7. 联想ERP项目实施案例分析(10):回到最初再反思IT价值
  8. Traceur 转码器
  9. 闪客工具:镜像服务的使用
  10. 无线网络密码破解WPA/WPA2教程(包教包会)