1.简单的字符串
对于“简单”字符串(通常适合一行),最简单的解决方案是使用fmt.Sprintf()
和朋友(fmt.Sprint()
, fmt.Sprintln()
)。这些类似于没有起始S
字母的函数,但这些Sxxx()
变体将结果作为 a 返回,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]"
对于仅连接string
s,您还可以使用strings.Join()
where 您可以指定自定义分隔符string
(放置在要连接的字符串之间)。
在Go Playground上试试这些。
2. 复杂的字符串(文档)
如果您尝试创建的字符串更复杂(例如,多行电子邮件),fmt.Sprintf()
则可读性和效率会降低(特别是如果您必须多次这样做)。
为此,标准库提供了包text/template
和html/template
. 这些包实现了用于生成文本输出的数据驱动模板。html/template
用于生成对代码注入安全的 HTML 输出。它提供与包相同的接口,text/template
并且应该text/template
在输出为 HTML 时使用。
使用这些template
包基本上需要您以值的形式提供一个静态模板string
(它可能源自一个文件,在这种情况下您只提供文件名),其中可能包含静态文本,以及在引擎处理模板并生成输出。
您可以提供静态模板中包含/替换的参数,这些参数可以控制输出生成过程。这种参数的典型形式是可以嵌套的struct
s 和values。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 $i}}, {{end}}{{.}}{{end}}
`
并提供这样的数据来执行它:
data := map[string]interface{}{
"Name": "Bob",
"UserName": "bob92",
"Roles": []string{"dbteam", "uiteam", "tester"},
}
通常模板的输出被写入 a io.Writer
,因此如果您希望结果为 a string
,请创建并写入 a bytes.Buffer
(实现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
: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上试试这个。