package main
import (
"fmt"
"strings"
"time"
)
func main() {
const col = 30
// Clear the screen by printing \x0c.
bar := fmt.Sprintf("\x0c[%%-%vs]", col)
for i := 0; i < col; i++ {
fmt.Printf(bar, strings.Repeat("=", i)+">")
time.Sleep(100 * time.Millisecond)
}
fmt.Printf(bar+" Done!", strings.Repeat("=", col))
}
第 12 行使用此格式动词语法“[%%-%vs]”。谁能解释一下它是如何解析的?双“%%”和“%vs”对我来说没有意义。谢谢。
尝试将其分成几部分并使用文字替换(例如 col 值)运行,但无法产生与运行示例所产生的结果相同的结果。
通过查看中间字符串进行一些调试:
然后,该字符串本身用作格式字符串,其中
%-30s
指示参数字符串应在右侧用空格字符填充,直到达到 30 个字符宽。%%
做一个百分号。%v
你可能知道。s
只是字母 s。因此,如果格式化的内容是数字 42,则结果是 string
%-42s
。当然,这本身就是一个有效的格式字符串。文档中对动词进行了解释:
以下是问题中的格式字符串如何转换为从 fmt.Sprintf 返回的字符串:
[
->[
%%
->%
-
->-
%v
-> 默认格式的值。s
->s
]
->]
这不是用于打印进度条或与之类似吗?
[%%-%vs]
根据我的理解,你看到的格式化动词[%%
是一个文字,[
后跟%%
. 是%%
表示单个字符的转义序列%
。所以,[%%
只代表[
后面跟着%
。%vs
是标准格式化动词,其中%v
是值占位符,s 表示要替换的值是字符串。%vs
本质上是一个字符串占位符。它告诉Printf
将其替换为格式字符串中下一个参数的值,该参数应该是一个字符串-
表示字符串的左对齐。因此,如果提供的字符串短于指定的宽度,则会在右侧填充空格以使其达到指定的宽度col
,在代码中动态设置为 30。因此,当您执行此代码时,它会打印一个进度条,该进度条随着循环迭代而增长。格式字符串
[%%-%vs]
会重复填充每次迭代时表示进度条的字符串,并具有不同长度的=
和>
字符。