1. Strings simples
Para seqüências de caracteres "simples" (normalmente o que se encaixa em uma linha), a solução mais simples é usar fmt.Sprintf()e amigos ( fmt.Sprint(), fmt.Sprintln()). Elas são análogas às funções sem a Sletra inicial , mas essas Sxxx()variantes retornam o resultado como a em stringvez de imprimi-las na saída padrão.
Por exemplo:
s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)
A variável sserá inicializada com o valor:
Hi, my name is Bob and I'm 23 years old.
Dica: Se você deseja concatenar valores de tipos diferentes, talvez não seja necessário usar automaticamente Sprintf()(o que requer uma cadeia de formatação) o que Sprint()é exatamente isso. Veja este exemplo:
i := 23
s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]"
Para concatenar apenas strings, você também pode usar strings.Join()onde você pode especificar um separador personalizado string(a ser colocado entre as seqüências de caracteres a serem unidas).
Experimente estes no Go Playground .
2. Strings complexas (documentos)
Se a string que você está tentando criar é mais complexa (por exemplo, uma mensagem de email com várias linhas), fmt.Sprintf()torna-se menos legível e menos eficiente (especialmente se você precisar fazer isso várias vezes).
Para isso, a biblioteca padrão fornece os pacotes text/templatee html/template. Esses pacotes implementam modelos orientados a dados para gerar saída de texto. html/templateé para gerar saída HTML segura contra injeção de código. Ele fornece a mesma interface que o pacote text/templatee deve ser usado em vez de text/templatesempre que a saída for HTML.
O uso dos templatepacotes exige basicamente que você forneça um modelo estático na forma de um stringvalor (que pode ser originário de um arquivo; nesse caso, você fornece apenas o nome do arquivo), que pode conter texto estático e ações que são processadas e executadas quando o arquivo O mecanismo processa o modelo e gera a saída.
Você pode fornecer parâmetros que são incluídos / substituídos no modelo estático e que podem controlar o processo de geração de saída. A forma típica de tais parâmetros éstruct s e mapvalores que podem ser aninhados.
Exemplo:
Por exemplo, digamos que você queira gerar mensagens de email com esta aparência:
Hi [name]!
Your account is ready, your user name is: [user-name]
You have the following roles assigned:
[role#1], [role#2], ... [role#n]
Para gerar corpos de mensagens de email como este, você pode usar o seguinte modelo estático:
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}}
`
E forneça dados como este para executá-lo:
data := map[string]interface{}{
"Name": "Bob",
"UserName": "bob92",
"Roles": []string{"dbteam", "uiteam", "tester"},
}
Normalmente, a saída dos modelos é gravada em um io.Writer, portanto, se você deseja o resultado como a string, crie e grave em um bytes.Buffer(que implementa io.Writer). Executando o modelo e obtendo o resultado comostring :
t := template.Must(template.New("email").Parse(emailTmpl))
buf := &bytes.Buffer{}
if err := t.Execute(buf, data); err != nil {
panic(err)
}
s := buf.String()
Isso resultará na saída esperada:
Hi Bob!
Your account is ready, your user name is: bob92
You have the following roles assigned:
dbteam, uiteam, tester
Experimente no Go Playground .
Observe também que, desde Go 1,10, uma alternativa mais recente, mais rápido, mais especializada está disponível para bytes.Buffero que é: strings.Builder. O uso é muito semelhante:
builder := &strings.Builder{}
if err := t.Execute(builder, data); err != nil {
panic(err)
}
s := builder.String()
Experimente este no Go Playground .
Nota: você também pode exibir o resultado da execução de um modelo se fornecer os.Stdoutcomo destino (que também implementa io.Writer):
t := template.Must(template.New("email").Parse(emailTmpl))
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
Isso gravará o resultado diretamente em os.Stdout. Tente isso no Playground Go .