Golang中switch case语句无法正确执行的原因及解决方法

Golang中switch case语句无法正确执行的原因及解决方法 你好,我最近几天一直在学习 Go。我正在编写一个简单的“shell”,当我使用 switch case 时,我需要在输入后加一个空格才能正常工作。例如,假设我有一个处理“quit”的 case,在输入我的“命令”时,我必须输入“quit ”而不是“quit”。在 Goland 或 repl.it 中运行我的代码时没有这个问题,但在 vscode 的终端或 Windows 终端中运行时,却出现了这种意外行为。以下是我的示例代码:

reader := bufio.NewReader(os.Stdin)

for {
    text, _ := reader.ReadString('\n')
    text = strings.Replace(text, "\n", "", -1)

    fullText := strings.Split(text, " ")

    switch fullText[0] {
    case "quit":
        os.Exit(-1)
    }
}

更多关于Golang中switch case语句无法正确执行的原因及解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复
[]string{"quit\r"}    -> quit
[]string{"quit", "\r"}-> quit

更多关于Golang中switch case语句无法正确执行的原因及解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好,

Windows 系统的打印输出是“\n\r”,因此你必须尝试使用“\r”或“\n\r”。

抱歉回复得有点晚。非常感谢大家的帮助!strings.TrimSpace 解决了问题!感谢你们对我犯的这样一个愚蠢错误如此耐心,并给出了如此详细精彩的回复。

是的,strings.TrimSpace 是有效的。 Nate,我已经复制了你的代码并进行了尝试。感谢你的发帖。

你是否尝试过通过输出一些信息来调试你的代码?

使用 fmt.Printf("%#v", fullText) 可能会给你一些启发。

从代码层面初步来看,似乎没有任何问题,它应该能正常工作。

在 Ubuntu 上使用 go run main.go 执行时,工作正常。 当在 Windows shell 中构建并运行时会发生什么?

我建议检查 text 在替换后(包含和不包含尾随空格)的内容。简单地将其作为字节切片打印出来。 这可能是一个 Windows 特有的问题。

请注意,这实际上不是一个 switch 语句的问题。

func main() {
    fmt.Println("hello world")
}

因此,您的一些终端使用Linux风格的换行符,而另一些则使用Windows风格的换行符。strings.TrimSpace 应该能帮到您。将其应用于输入字符串。或者,如果您想明确允许尾随空格,可以使用 strings.Trim 并指定 "\r"

func main() {
    fmt.Println("hello world")
}

在你的代码中,bufio.Reader.ReadString('\n') 会读取输入直到遇到换行符,但换行符本身也会被包含在返回的字符串中。你使用 strings.Replace 来移除换行符,这是正确的。然而,问题可能在于不同操作系统或终端环境下的换行符差异,以及输入字符串末尾可能存在的空格或不可见字符。

在 Windows 系统中,换行符通常是 \r\n(回车加换行),而你的代码只移除了 \n,可能遗留了 \r。这会导致 fullText[0] 包含 \r,从而与 "quit" 不匹配。例如,输入 quit 后,实际字符串可能是 "quit\r",这需要输入 "quit "(加空格)来让 strings.Split 分割出 "quit"(因为 "quit\r" 不会被分割,而 "quit \r" 会分割出 "quit")。

解决方法:使用 strings.TrimSpace 来移除所有空白字符(包括空格、制表符、换行符、回车符等),确保输入干净。修改你的代码如下:

reader := bufio.NewReader(os.Stdin)

for {
    text, _ := reader.ReadString('\n')
    text = strings.TrimSpace(text) // 使用 TrimSpace 移除所有空白字符

    fullText := strings.Split(text, " ")

    switch fullText[0] {
    case "quit":
        os.Exit(-1)
    }
}

这样,无论输入 quitquit 还是 quit\r\ntext 都会被清理为 "quit",从而正确匹配 case。如果问题仍然存在,可以添加调试输出(如 fmt.Printf("%q\n", fullText[0]))来检查 fullText[0] 的实际内容。

回到顶部