不打印就格式化Go字符串?

2024-04-23 10:30:37 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有一种不打印字符串的简单方法来格式化Go中的字符串?

我能做到:

bar := "bar"
fmt.Printf("foo: %s", bar)

但我希望返回格式化的字符串,而不是打印出来,这样我可以进一步操作它。

我也可以这样做:

s := "foo: " + bar

但是,当格式字符串很复杂时,这会变得很难读取,当一个或多个部分不是字符串并且必须首先转换时,这会变得很麻烦,比如

i := 25
s := "foo: " + strconv.Itoa(i)

有更简单的方法吗?


Tags: 方法字符串gofoo格式barprintffmt
3条回答

在您的例子中,需要使用Sprintf()来格式化字符串。

func Sprintf(format string, a ...interface{}) string

根据格式说明符的Sprintf格式并返回结果字符串。

s := fmt.Sprintf("Good Morning, This is %s and I'm living here from last %d years ", "John", 20)

您的输出将是:

Good Morning, This is John and I'm living here from last 20 years.

Sprintf是你要找的。

示例

fmt.Sprintf("foo: %s", bar)

您还可以在Errors example中看到它作为“围棋之旅”的一部分正在使用

return fmt.Sprintf("at %v, %s", e.When, e.What)

一。简单字符串

对于“简单”字符串(通常适合一行),最简单的解决方案是使用^{}和friends(^{}^{})。这些函数类似于没有起始字母的函数,但是这些变量返回的结果是string,而不是打印到标准输出。

例如:

s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)

变量s将使用以下值初始化:

Hi, my name is Bob and I'm 23 years old.

提示:如果只想连接不同类型的值,则可能不需要自动使用Sprintf()(需要格式字符串),因为Sprint()正是这样做的。请参见以下示例:

i := 23
s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]"

对于仅连接strings,也可以使用^{},在这里可以指定自定义分隔符string(放置在要连接的字符串之间)。

Go Playground上试试这些。

2。复杂字符串(文档)

如果您试图创建的字符串更复杂(例如,多行电子邮件),那么fmt.Sprintf()的可读性和效率就会降低(尤其是在必须多次这样做的情况下)。

为此,标准库提供了包^{}^{}。这些包实现了用于生成文本输出的数据驱动模板。html/template用于生成对代码注入安全的HTML输出。它提供与包text/template相同的接口,当输出为HTML时,应该使用它而不是text/template

使用template包基本上要求您提供一个string值形式的静态模板(在这种情况下,您只提供文件名),该值可能包含静态文本,以及在引擎处理模板并生成输出时处理和执行的操作。

您可以提供静态模板中包含/替换的参数,这些参数可以控制输出生成过程。这些参数的典型形式是structs和map值,它们可以嵌套。

示例:

例如,假设您要生成如下所示的电子邮件:

Hi [name]!

Your account is ready, your user name is: [user-name]

You have the following roles assigned:
[role#1], [role#2], ... [role#n]

要生成这样的电子邮件正文,可以使用以下静态模板:

const emailTmpl = `Hi {{.Name}}!

Your account is ready, your user name is: {{.UserName}}

You have the following roles assigned:
{{range $i, $r := .Roles}}{{if ne $i 0}}, {{end}}{{.}}{{end}}
`

并提供这样的数据来执行它:

data := map[string]interface{}{
    "Name":     "Bob",
    "UserName": "bob92",
    "Roles":    []string{"dbteam", "uiteam", "tester"},
}

通常,模板的输出被写入^{},因此如果希望结果是string,请创建并写入^{}(实现io.Writer)。执行模板并将结果作为string

t := template.Must(template.New("email").Parse(emailTmpl))
buf := &bytes.Buffer{}
if err := t.Execute(buf, data); err != nil {
    panic(err)
}
s := buf.String()

这将产生预期的输出:

Hi Bob!

Your account is ready, your user name is: bob92

You have the following roles assigned:
dbteam, uiteam, tester

Go Playground上试试。

还请注意,自从Go 1.10以来,bytes.Buffer有一个更新、更快、更专业的替代方案,即:^{}。用法非常相似:

builder := &strings.Builder{}
if err := t.Execute(builder, data); err != nil {
    panic(err)
}
s := builder.String()

Go Playground上试试这个。

注意:如果提供os.Stdout作为目标(它还实现io.Writer),则还可以显示模板执行的结果:

t := template.Must(template.New("email").Parse(emailTmpl))
if err := t.Execute(os.Stdout, data); err != nil {
    panic(err)
}

这将直接将结果写入os.Stdout。在Go Playground上试试这个。

相关问题 更多 >