1. Proste ciągi
W przypadku „prostych” ciągów znaków (zazwyczaj pasujących do linii) stosuje się najprostsze rozwiązanie fmt.Sprintf() i znajomych ( fmt.Sprint(), fmt.Sprintln()). Są one analogiczne do funkcji bez Slitery początkowej , ale te Sxxx()warianty zwracają wynik stringzamiast wypisywać je na standardowe wyjście.
Na przykład:
s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)
Zmienna szostanie zainicjowana wartością:
Hi, my name is Bob and I'm 23 years old.
Wskazówka: Jeśli chcesz po prostu połączyć wartości różnych typów, może nie być konieczne automatyczne użycie Sprintf()(co wymaga ciągu formatującego), jak Sprint()to dokładnie robi. Zobacz ten przykład:
i := 23
s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]"
W przypadku łączenia tylko stringmożesz użyć strings.Join()miejsca, w którym możesz określić niestandardowy separator string(umieszczany między ciągami znaków do połączenia).
Wypróbuj je na Go Playground .
2. Złożone ciągi (dokumenty)
Jeśli ciąg, który próbujesz utworzyć, jest bardziej złożony (np. Wieloliniowa wiadomość e-mail), fmt.Sprintf() staje się mniej czytelny i mniej wydajny (zwłaszcza jeśli musisz to zrobić wiele razy).
W tym celu standardowa biblioteka udostępnia pakiety text/templatei html/template. Pakiety te implementują szablony oparte na danych do generowania tekstu wyjściowego. html/templatesłuży do generowania danych wyjściowych HTML zabezpieczonych przed wstrzyknięciem kodu. Zapewnia ten sam interfejs co pakiet text/templatei powinien być używany zamiast text/templatezawsze, gdy wyjściem jest HTML.
Używając template pakietów zasadniczo wymaga dostarczenia szablonu statycznego w postaci stringwartości (która może pochodzić z pliku, w którym to przypadku podajesz tylko nazwę pliku), która może zawierać tekst statyczny oraz działań, które są przetwarzane i wykonywane, gdy silnik przetwarza szablon i generuje dane wyjściowe.
Możesz podać parametry, które są zawarte / podstawione w szablonie statycznym i które mogą kontrolować proces generowania danych wyjściowych. Typową formą takich parametrów sąstructmap wartości i wartości, które mogą być zagnieżdżone.
Przykład:
Załóżmy na przykład, że chcesz generować wiadomości e-mail wyglądające tak:
Hi [name]!
Your account is ready, your user name is: [user-name]
You have the following roles assigned:
[role#1], [role#2], ... [role#n]
Aby wygenerować takie treści wiadomości e-mail, możesz użyć następującego szablonu statycznego:
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}}
`
I podaj dane do wykonania:
data := map[string]interface{}{
"Name": "Bob",
"UserName": "bob92",
"Roles": []string{"dbteam", "uiteam", "tester"},
}
Zwykle dane wyjściowe szablonów są zapisywane do io.Writer, więc jeśli chcesz wynik jako string, utwórz i zapisz do bytes.Buffer(który implementuje io.Writer). Wykonanie szablonu i uzyskanie wyniku jako 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()
Spowoduje to oczekiwany wynik:
Hi Bob!
Your account is ready, your user name is: bob92
You have the following roles assigned:
dbteam, uiteam, tester
Wypróbuj na placu zabaw Go .
Należy również pamiętać, że od idź 1.10, nowsze, szybsze, bardziej wyspecjalizowane alternatywą jest dostępny na bytes.Bufferktórym jest: strings.Builder. Użycie jest bardzo podobne:
builder := &strings.Builder{}
if err := t.Execute(builder, data); err != nil {
panic(err)
}
s := builder.String()
Wypróbuj ten na Play Playground .
Uwaga: możesz również wyświetlić wynik wykonania szablonu, jeśli podasz os.Stdoutjako cel (który również implementuje io.Writer):
t := template.Must(template.New("email").Parse(emailTmpl))
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
Spowoduje to zapisanie wyniku bezpośrednio do os.Stdout. Wypróbuj to na placu zabaw Go .