退格键在 Go playground 中不起作用

Backspace character does not work in the Go playground

我是 Go 新手。刚刚了解了fmt.Println()的各种用法。我尝试了以下内容 in the official playground 但得到了意想不到的输出。请解释我理解中哪里出错了。

输入:fmt.Println("hi\b", "there!")
输出:hi� there!
预期:h there!

输入:fmt.Println("hi", '\b', "there!")
输出:hi 8 there!
预期:hithere!...假设符文没有附加空格

输入:fmt.Println("hi", "\bthere!")
输出:hi �there!
预期:hithere!


(注意:以上,占位符已被 U+FFFD 替换,因为原始字符在环境之间呈现不一致。)

首先要检查的是您的终端,'\b' 取决于终端,检查终端 运行 您的程序是否将其处理为“将光标向后移动一个字符”(大多数 unixes-like会的,我不知道 Windows),你的第一个和第三个给出的例子完全符合你在我的终端上的期望 (st)。

input: fmt.Println("hi", '\b', "there!")

output: hi 8 there!

expected: hithere!... assuming runes are not appended with spaces

这里你的假设不是包 fmt 的作用:

For each Printf-like function, there is also a Print function that takes no format and is equivalent to saying %v for every operand. Another variant Println inserts blanks between operands and appends a newline.

Fmt 将符文的 %v 处理为 %d,而不是 %c,因此 '\b' 的格式为“8”(ascii 值 56),而不是 '\b '(ascii 值 8)。如果它们在两个参数之间,符文也会有一个 space。

Println 对此输入所做的是:

print string "hi"

print space

format number 8 then print string "8"

print space

print string "there!"

要调试渲染不可见字符等问题,我建议您使用 encoding/hex 包,例如:

package main

import (
    "encoding/hex"
    "fmt"
    "os"
)

func main() {
    d := hex.Dumper(os.Stdout)
    defer d.Close()

    fmt.Fprintln(d, "hi", '\b', "there!")
}

输出:00000000 68 69 20 38 20 74 68 65 72 65 21 0a |hi 8 there!.| 游乐场:https://go.dev/play/p/F-I2mdh43K7

您的程序完全按照您的要求输出。问题主要出在您的输出查看器上。

控制字符和序列只有在发送到兼容的虚拟控制台(或物理终端、打印机或电传打字机;但后者现在很少见)时才会产生预期效果。 Go playground 所做的是捕获程序的输出 as-is 并将其原封不动地发送到浏览器进行显示。浏览器不解释终端控制代码(换行符除外,甚至只是有时);相反,它希望通过 HTML 标记来传达格式。由于退格字符没有指定的字形,浏览器通常会显示一个占位符字形,或者有时根本不显示任何字形。

如果 运行 你的 Go 程序在你的本地机器上,你将它的输出重定向到一个文本文件,然后在文本编辑器中打开该文件,你会得到类似的效果:编辑器不会解释文本文件中包含的任何转义序列;有时它甚至会主动阻止控制字符被显示编辑器的终端解释(如果它恰好是 console-based 编辑器),通过替换字符的符号,常规表示,如 ^H.

在中间的示例中,'\b' 字面值计算为一个整数,其值为字符的 Unicode 代码点编号(Go 称之为“符文”)。这是 explained in the specification:

A rune literal represents a rune constant, an integer value identifying a Unicode code point. A rune literal is expressed as one or more characters enclosed in single quotes, as in 'x' or '\n'. Within the quotes, any character may appear except newline and unescaped single quote. A single quoted character represents the Unicode value of the character itself, while multi-character sequences beginning with a backslash encode values in various formats.

由于'\b'表示U+0008,所以传递给fmt.Println的是整数值8。函数然后将整数打印为其十进制表示,而不是将其解释为字符代码.