1. 简单的字符串
对于“简单”字符串(通常是适合一行的字符串),最简单的解决方案是使用fmt.Sprintf()和友元(fmt.Sprint(), fmt.Sprintln())。这些函数类似于没有开头字母S的函数,但是这些Sxxx()变量将结果作为字符串返回,而不是将它们打印到标准输出。
例如:
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. join(),其中您可以指定一个自定义分隔符字符串(放置在要连接的字符串之间)。
在Go Playground上试试这些。
2. 复杂字符串(文档)
如果您试图创建的字符串更复杂(例如多行电子邮件消息),fmt.Sprintf()变得更不可读,效率更低(特别是如果您必须多次这样做)。
为此,标准库提供了包text/template和html/template。这些包实现了用于生成文本输出的数据驱动模板。html/template用于生成针对代码注入的安全html输出。它提供了与包文本/模板相同的接口,当输出是HTML时应该使用它而不是文本/模板。
使用模板包基本上需要您以字符串值的形式提供一个静态模板(它可能起源于一个文件,在这种情况下您只需要提供文件名),它可能包含静态文本,以及引擎处理模板并生成输出时处理和执行的操作。
您可以提供包含在静态模板中的参数,这些参数可以控制输出生成过程。这种参数的典型形式是可以嵌套的结构和映射值。
例子:
例如,假设你想生成这样的电子邮件消息:
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 $i}}, {{end}}{{.}}{{end}}
`
并为执行它提供这样的数据:
data := map[string]interface{}{
"Name": "Bob",
"UserName": "bob92",
"Roles": []string{"dbteam", "uiteam", "tester"},
}
模板的输出通常被写入io。写入器,因此如果您希望结果作为字符串,则创建并写入字节。Buffer(实现io.Writer)。执行模板并以字符串形式获取结果:
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以来,字节可以使用一个更新、更快、更专门的替代方案。Buffer,也就是:strings。builder。用法非常相似:
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上试试这个。