本文共 14408 字,大约阅读时间需要 48 分钟。
用switch语句编写程序
give programmers the ability to direct their programs to take some action if a condition is true and another action if the condition is false. Frequently, we want to compare some against multiple possible values, taking different actions in each circumstance. It’s possible to make this work using alone. Writing software, however, is not only about making things work but also communicating your intention to your future self and other developers. switch
is an alternative conditional statement useful for communicating actions taken by your Go programs when presented with different options.
使程序员能够指导他们的程序在条件为真时采取某些措施,在条件为假时采取另一种措施。 通常,我们希望将某个与多个可能的值进行比较,并在每种情况下采取不同的操作。 可以单独使用来完成这项工作。 但是,编写软件不仅要使事情正常进行,而且还要与未来的自己和其他开发人员交流您的意图。 switch
是另一种条件语句,可用于在显示不同选项时传达Go程序所执行的操作。
Everything we can write with the switch statement can also be written with if
statements. In this tutorial, we’ll look at a few examples of what the switch statement can do, the if
statements it replaces, and where it’s most appropriately applied.
我们可以使用switch语句编写的所有内容也可以使用if
语句编写。 在本教程中,我们将看一些switch语句可以执行的操作,替换if
语句以及最合适地使用它的示例。
Switch is commonly used to describe the actions taken by a program when a variable is assigned specific values. The following example demonstrates how we would accomplish this using if
statements:
开关通常用于描述在为变量分配特定值时程序所执行的操作。 以下示例演示了如何使用if
语句完成此操作:
package mainimport "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") }}
This will generate the following output:
这将生成以下输出:
Output chocolate is great!vanilla is great!strawberry is my favorite!I've never tried banana before
Within main
, we define a of ice-cream flavors. We then use a to iterate through them. We use three if
statements to print out different messages indicating preferences for different ice-cream flavors. Each if
statement must use the continue
statement to stop execution of the for
loop so that the default message at the end is not printed for the preferred ice-cream flavors.
在main
,我们定义了冰淇淋口味。 然后,我们使用遍历它们。 我们使用三个if
语句来打印出不同的消息,以表示对不同冰淇淋口味的偏好。 每个if
语句都必须使用continue
语句来停止执行for
循环,这样,对于首选的冰淇淋口味,末尾的默认消息不会被打印出来。
As we add new ice-cream preferences, we have to keep adding if
statements to handle the new cases. Duplicated messages, as in the case of "vanilla"
and "chocolate"
, must have duplicated if
statements. To future readers of our code (ourselves included), the repetitive nature of the if
statements obscures the important part of what they are doing—comparing the variable against multiple values and taking different actions. Also, our fallback message is set apart from the conditionals, making it appear unrelated. The switch
statement can help us organize this logic better.
在添加新的冰淇淋偏好设置时,我们必须继续添加if
语句来处理新情况。 重复的消息(例如"vanilla"
和"chocolate"
)必须具有重复的if
语句。 对于我们的代码的未来读者(包括我们自己), if
语句的重复性质掩盖了他们正在执行的重要工作-将变量与多个值进行比较并采取不同的操作。 此外,我们的后备消息与条件语句分开设置,使其显得无关紧要。 switch
语句可以帮助我们更好地组织这种逻辑。
The switch
statement begins with the switch
keyword and is followed, in its most basic form, with some variable to perform comparisons against. This is followed by a pair of curly braces ({}
) where multiple case clauses can appear. Case clauses describe the actions your Go program should take when the variable provided to the switch statement equals the value referenced by the case clause. The following example converts the previous example to use a switch
instead of multiple if
statements:
switch
语句以switch
关键字开头,然后以最基本的形式后面跟一些变量进行比较。 随后是一对花括号( {}
),其中可以出现多个case子句 。 Case子句描述了当提供给switch语句的变量等于case子句引用的值时,Go程序应采取的动作。 下面的示例将前面的示例转换为使用switch
而不是多个if
语句:
package mainimport "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") } }}
The output is the same as before:
输出与之前相同:
Output chocolate is great!vanilla is great!strawberry is my favorite!I've never tried banana before
We’ve once again defined a slice of ice-cream flavors in main
and used the range
statement to iterate over each flavor. This time, however, we’ve used a switch
statement that will examine the flav
variable. We use two case
clauses to indicate preferences. We no longer need continue
statements as only one case
clause will be executed by the switch
statement. We’re also able to combine the duplicated logic of the "chocolate"
and "vanilla"
conditionals by separating each with a comma in the declaration of the case
clause. The default
clause serves as our catch-all clause. It will run for any flavors that we haven’t accounted for in the body of the switch
statement. In this case, "banana"
will cause default
to execute, printing the message I've never tried banana before
.
我们再次在main
range
定义了一片冰淇淋口味,并使用range
语句遍历每种口味。 但是,这一次,我们使用了switch
语句,它将检查flav
变量。 我们使用两个case
子句来表示首选项。 我们不再需要continue
语句,因为switch
语句将只执行一个case
子句。 通过在case
子句的声明中用逗号分隔每个条件,我们还可以组合"chocolate"
和"vanilla"
条件的重复逻辑。 default
子句用作我们的包罗万象的子句。 它可以运行switch
语句正文中未考虑的任何口味。 在这种情况下, "banana"
将导致default
执行,并打印一条I've never tried banana before
的消息。
This simplified form of switch
statements addresses the most common use for them: comparing a variable against multiple alternatives. It also provides conveniences for us where we want to take the same action for multiple different values and some other action when none of the listed conditions are met by using the provided default
keyword.
switch
语句的这种简化形式解决了它们的最常见用法:将变量与多个替代方案进行比较。 当我们希望对多个不同的值采取相同的操作,而又不想使用提供的default
关键字满足列出的条件时采取其他措施时,这也为我们提供了便利。
When this simplified form of switch
proves too limiting, we can use a more general form of switch
statement.
当这种简化的switch
形式证明过于局限时,我们可以使用更通用的switch
语句形式。
switch
statements are useful for grouping collections of more complicated conditionals to show that they are somehow related. This is most commonly used when comparing some variable against a range of values, rather than specific values as in the earlier example. The following example implements a guessing game using if
statements that could benefit from a switch
statement:
switch
语句可用于对更复杂的条件集合进行分组,以表明它们之间存在某种关联。 在将某个变量与一系列值进行比较时,最常用此方法,而不是像前面的示例中那样将特定值进行比较。 以下示例使用可以从switch
语句中受益的if
语句实现一个猜谜游戏:
package mainimport ( "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 }}
The output will vary depending on the random number selected and how well you play the game. Here is the output from one example session:
输出将根据所选的随机数和您玩游戏的程度而有所不同。 这是一个示例会话的输出:
Output Enter a guess: 10Too low!Enter a guess: 15Too low!Enter a guess: 18Too high!Enter a guess: 17You win!
Our guessing game needs a random number to compare guesses against, so we use the rand.Intn
function from the math/rand
package. To make sure we get different values for target
each time we play the game, we use rand.Seed
to randomize the random number generator based on the current time. The argument 100
to rand.Intn
will give us a number in the range 0–100. We then use a for
loop to begin collecting guesses from the player.
我们的猜测游戏需要一个随机数来比较猜测,因此我们使用math/rand
软件包中的rand.Intn
函数。 为了确保每次玩游戏时我们都能获得不同的target
,我们使用rand.Seed
根据当前时间随机化随机数生成器。 rand.Intn
的参数100
将给我们一个介于0-100之间的数字。 然后,我们使用for
循环开始收集玩家的猜测。
The fmt.Scanf
function gives us a means to read user input into a variable of our choosing. It takes a format string verb that converts the user’s input into the type we expect. %d
here means we expect an int
, and we pass the address of the guess
variable so that fmt.Scanf
is able to set that variable. After we then use two if
statements to compare the user’s guess to the target
value. The string
that they return, along with bool
, controls the message displayed to the player and whether the game will exit.
fmt.Scanf
函数为我们提供了一种将用户输入读取到我们选择的变量中的方法。 它采用格式字符串动词,该动词会将用户的输入转换为我们期望的类型。 这里的%d
表示我们期望一个int
,并且我们传递guess
变量的地址,以便fmt.Scanf
可以设置该变量。 我们然后使用两个if
语句将用户的猜测与target
进行比较。 他们返回的string
和bool
一起控制显示给玩家的消息以及游戏是否退出。
These if
statements obscure the fact that the range of values that the variable is being compared against are all related in some way. It can also be difficult, at a glance, to tell if we missed some part of the range. The next example refactors the previous example to use a switch
statement instead:
这些if
语句掩盖了将变量与之进行比较的值范围都以某种方式相关的事实。 乍一看,很难判断我们是否错过了该范围的某些部分。 下一个示例将前面的示例重构为使用switch
语句代替:
package mainimport ( "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 } }}
This will generate output similar to the following:
这将产生类似于以下内容的输出:
Output Enter a guess: 25Too low!Enter a guess: 28Too high!Enter a guess: 27You win!
In this version of the guessing game, we’ve replaced the block of if
statements with a switch
statement. We omit the expression argument to switch
because we are only interested in using switch
to collect conditionals together. Each case
clause contains a different expression comparing guess
against target
. Similar to the first time we replaced if
statements with switch
, we no longer need continue
statements since only one case
clause will be executed. Finally, the default
clause handles the case where guess == target
since we have covered all other possible values with the other two case
clauses.
在此版本的猜谜游戏中,我们用switch
语句替换了if
语句块。 我们省略了表达式参数switch
因为我们只对使用switch
一起收集条件集感兴趣。 每个case
子句包含一个不同的表达式,将guess
与target
进行比较。 与第一次用switch
替换if
语句类似,我们不再需要continue
语句,因为将只执行一个case
子句。 最后, default
子句处理guess == target
的情况,因为我们用其他两个case
子句覆盖了所有其他可能的值。
In the examples that we’ve seen so far, exactly one case statement will be executed. Occasionally, you may wish to combine the behaviors of multiple case
clauses. switch
statements provide another keyword for achieving this behavior.
在到目前为止的示例中,将仅执行一个case语句。 有时,您可能希望合并多个case
子句的行为。 switch
语句为实现此行为提供了另一个关键字。
Sometimes you will want to reuse the code that another case
clause contains. In these cases, it’s possible to ask Go to run the body of the next case
clause listed using the fallthrough
keyword. This next example modifies our earlier ice cream flavor example to more accurately reflect our enthusiasm for strawberry ice cream:
有时您会想重用另一个case
子句包含的代码。 在这些情况下,可以要求Go使用fallthrough
关键字运行列出的下一个case
子句的正文。 下一个示例修改了我们先前的冰淇淋口味示例,以更准确地反映我们对草莓冰淇淋的热情:
package mainimport "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") } }}
We will see this output:
我们将看到以下输出:
Output chocolate is great!vanilla is great!strawberry is my favorite!strawberry is great!I've never tried banana before
As we’ve seen previously, we define a slice of string
to represent flavors and iterate through this using a for
loop. The switch
statement here is identical to the one we’ve seen before, but with the addition of the fallthrough
keyword at the end of the case
clause for "strawberry"
. This will cause Go to run the body of case "strawberry":
, first printing out the string strawberry is my favorite!
. When it encounters fallthrough
it will run the body of the next case
clause. This will cause the body of case "vanilla", "chocolate":
to run, printing strawberry is great!
.
正如我们之前所见,我们定义了一个string
切片来表示风味,并使用for
循环对其进行迭代。 这里的switch
语句与我们之前看到的相同,但是在case
子句的尾部为"strawberry"
添加了fallthrough
关键字。 这将导致Go运行case "strawberry":
的主体case "strawberry":
, strawberry is my favorite!
先打印出串状strawberry is my favorite!
。 当遇到fallthrough
,它将运行下一个case
子句的主体。 这将导致case "vanilla", "chocolate":
的case "vanilla", "chocolate":
运行,印制strawberry is great!
。
The fallthrough
keyword is not used often by Go developers. Usually, the code reuse realized by using fallthrough
can be better obtained by defining a function with the common code. For these reasons, using fallthrough
is generally discouraged.
Go开发人员通常不使用fallthrough
关键字。 通常,通过使用通用代码定义一个函数,可以更好地获得使用fallthrough
实现的代码重用。 由于这些原因,通常不建议使用fallthrough
。
switch
statements help us convey to other developers reading our code that a set of comparisons are somehow related to each other. They make it much easier to add different behavior when a new case is added in the future and make it possible to ensure that anything we forgot is handled properly as well with default
clauses. The next time you find yourself writing multiple if
statements that all involve the same variable, try rewriting it with a switch
statement—you’ll find it easier to rework when it comes time to consider some other alternative value.
switch
语句帮助我们传达给其他开发人员,这些开发人员在阅读我们的代码时发现一组比较之间存在某种关联。 它们使将来添加新案例时添加不同的行为变得容易得多,并且可以确保使用default
子句正确处理我们遗忘的所有内容。 下次您发现自己编写了多个都包含相同变量的if
语句时,请尝试使用switch
语句重写它-当需要考虑其他一些替代值时,您会发现返工更容易。
If you’d like to learn more about the Go programming language, check out the entire .
如果您想了解有关Go编程语言的更多信息,请阅读完整的“ 在Go中编写 。
翻译自:
用switch语句编写程序
转载地址:http://uxhgb.baihongyu.com/