switch case语句会继续执行默认情况。

huangapple go评论89阅读模式
英文:

Switch case statement falls through to default

问题

我是你的中文翻译助手,以下是翻译好的内容:

我刚开始学习Go语言,但是无法理解为什么最后的case子句(connect和test)会落入到default中。但是带有换行符的那些子句(exit\r\n和connect\r\n)却不会。

在Go语言中没有fallthrough语句。

我尝试给switch语句加上标签并使用break [lbl]来调用,但是default块仍然会被执行。

package main

import (
	"fmt"
	"strings"
	"bufio"
	"os"
)

func main() {
	
	var cmd string
	bio := bufio.NewReader(os.Stdin)
	fmt.Println("Hello")
	
	proceed := true
	
	for proceed {

		fmt.Print(">>> ")
		cmd, _ = bio.ReadString('\n')
		cmds := strings.Split(cmd, " ")

		for i := range cmds{
			switch cmds[i]{
				case "exit\r\n" :
					proceed = false
				case "connect\r\n":
					fmt.Println("The connect command requires more input")
				case "connect":
					if i + 2 >= len(cmds) {
						fmt.Println("Connect command usage: connect host port")
					} else {
						i++
						constring := cmds[i]
						i++
						port := cmds[i]
						con(constring, port)	
					}
					fmt.Println("不要打印其他内容,不要落入到default中。没有理由执行default子句吧???")
				case "test":
					fmt.Println("不要打印其他内容,不要落入到default中。没有理由执行default子句吧???")
				default:
					fmt.Println("无法识别的命令:" + cmds[i])
			} 
			
		}

	}
}

func con (conStr, port string){
	panic (conStr)
}

希望对你有帮助!如果还有其他问题,请随时提问。

英文:

I am new to go and can't figure out why the last case clauses (connect and test) fall through to default. But the ones with the new line characters (exit\r\n and connect\r\n) don't

There is no fallthrough statement.

I've tried labeling the switch and calling break [lbl] but the default block still gets executed

package main

import (
"fmt"
"strings"
"bufio"
"os"
)

func main() {

var cmd string
bio := bufio.NewReader(os.Stdin)
fmt.Println("Hello")

proceed := true

for proceed {

	fmt.Print(">> ")
	cmd, _ = bio.ReadString('\n')
	cmds := strings.Split(cmd, " ")

	for i := range cmds{
		switch cmds[i]{
			case "exit\r\n" :
				proceed = false
			case "connect\r\n":
				fmt.Println("The connect command requires more input")
			case "connect":
				if i + 2 >= len(cmds) {
					fmt.Println("Connect command usage: connect host port")
				} else {
					i++
					constring := cmds[i]
					i++
					port := cmds[i]
					con(constring, port)	
				}
				fmt.Println("dont print anything else, dont fall through to default. There should be no reason why the default caluse is executed???")
			case "test":
				fmt.Println("dont print anything else, dont fall through to default. There should be no reason why the default caluse is executed???")
			default:
				fmt.Println("Unrecognised command: " + cmds[i])
		} 
		
	}

}
}

func con (conStr, port string){
panic (conStr)
}

答案1

得分: 1

《Go编程语言规范》

Switch语句

"Switch"语句提供了多路执行的功能。一个表达式或类型说明符会与"cases"进行比较。

表达式switch

在表达式switch中,会先计算switch表达式,然后从左到右、从上到下依次计算case表达式(它们不需要是常量)。第一个与switch表达式相等的case会触发执行与之关联的语句,其他的case会被跳过。如果没有匹配的case,并且存在"default" case,则会执行"default" case中的语句。一个switch语句中最多只能有一个"default" case,并且它可以出现在任何位置。如果缺少switch表达式,则相当于布尔值true。

ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" StatementList .
ExprSwitchCase = "case" ExpressionList | "default" .

最后的switch case子句("connect"和"test")不会继续执行"default" case子句。在switch语句的case子句中,break语句会跳出switch语句,而不是跳出周围的for子句。

你没有提供一个可重现的示例:如何创建一个最小、完整且可验证的示例。例如,你没有展示输入和输出。

这是一个正常工作的示例。有一个原因导致执行"default"子句。

>> test 127.0.0.1 8080
不要打印其他内容,不要继续执行"default"。没有理由执行"default"子句???
未识别的命令:127.0.0.1
未识别的命令:8080

>>

cmds的值是["test" "127.0.0.1" "8080\r\n"]

你的程序逻辑有严重缺陷。

英文:

> The Go Programming Language Specification
>
> Switch statements
>
> "Switch" statements provide multi-way execution. An expression or type
> specifier is compared to the "cases" inside
>
> Expression switches
>
> In an expression switch, the switch expression is evaluated and the
> case expressions, which need not be constants, are evaluated
> left-to-right and top-to-bottom; the first one that equals the switch
> expression triggers execution of the statements of the associated
> case; the other cases are skipped. If no case matches and there is a
> "default" case, its statements are executed. There can be at most one
> default case and it may appear anywhere in the "switch" statement. A
> missing switch expression is equivalent to the boolean value true.
>
> ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
> ExprCaseClause = ExprSwitchCase ":" StatementList .
> ExprSwitchCase = "case" ExpressionList | "default" .

The last switch case clauses ("connect" and "test") do not fall through to the default case clause. A break statement in a switch statement case clause breaks out of the switch statement; it does not break out of a surrounding for clause.

You have not provided us with a reproducible example: How to create a Minimal, Complete, and Verifiable example.. For example, you haven't shown us your input and output.

Here's an example, which is working as expected. There is a reason that the default clause is executed.

>> test 127.0.0.1 8080
dont print anything else, dont fall through to default. There should be no reason why the default caluse is executed???
Unrecognised command: 127.0.0.1
Unrecognised command: 8080

>> 

The value of cmds, fmt.Printf("%q\n", cmds), is ["test" "127.0.0.1" "8080\r\n"].

Your program logic is badly flawed.

答案2

得分: -1

尝试使用strings.Trim()将您的switch语句的主题包装起来,像这样:

switch strings.TrimSpace(cmds[i]) {
   // your cases
}

总的来说,看起来内部的for循环在这种情况下是错误的结构。根据这段代码,您可能希望删除该循环,并将cmds数组的第一个元素作为switch语句的主题。

英文:

Try wrapping the subject of your switch statement with strings.Trim() like so:

switch strings.TrimSpace(cmds[i]) {
   // your cases
}

In general though, it looks like the inner for loop is the wrong construct to be using in this case. Based on this snippet of code you probably want to remove that and just have the first element of the cmds array be the subject of your switch statement

huangapple
  • 本文由 发表于 2015年11月13日 09:16:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/33684386.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定