Golang:没有打印的字符串格式?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (130)

有没有一种简单的方法可以在不打印字符串的情况下格式化一个字符串?

我能做到:

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

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

我也可以这样做:

s := "foo: " + bar

但是,当格式字符串很复杂时,就很难读懂它,而当其中一个或多个部分不是字符串时,就变得很麻烦,并且必须先转换,例如

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

我是个新手--我的背景是Ruby,这很简单。有更简单的方法吗?

提问于
用户回答回答于

1.简单字符串

对于“简单”字符串(通常适合行),最简单的解决方案是使用fmt.Sprintf() and friends (fmt.Sprint(),,,fmt.Sprintln()).它们类似于没有启动器的功能S信,但是这些Sxxx()变量将结果作为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,您也可以使用strings.Join()可以在其中指定自定义分隔符。string(放置在要连接的字符串之间)。

试试这些围棋游乐场...

2.复杂字符串(文件)

如果要创建的字符串更复杂(例如,多行电子邮件消息),fmt.Sprintf()可读性降低,效率降低(特别是当你不得不这样做很多次的时候)。

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

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

您可以提供静态模板中包含/替换的参数,这些参数可以控制输出生成过程。这类参数的典型形式如下structs and 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"},
}

通常,模板的输出将写入io.Writer,所以如果您希望将结果作为string,创建并写入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

试一试这个...

注意:如果只提供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.

用户回答回答于

扫码关注云+社区

领取腾讯云代金券