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 S
litery początkowej , ale te Sxxx()
warianty zwracają wynik string
zamiast 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 s
zostanie 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 string
moż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/template
i html/template
. Pakiety te implementują szablony oparte na danych do generowania tekstu wyjściowego. html/template
służy do generowania danych wyjściowych HTML zabezpieczonych przed wstrzyknięciem kodu. Zapewnia ten sam interfejs co pakiet text/template
i powinien być używany zamiast text/template
zawsze, gdy wyjściem jest HTML.
Używając template
pakietów zasadniczo wymaga dostarczenia szablonu statycznego w postaci string
wartoś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ąstruct
map
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.Buffer
któ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.Stdout
jako 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 .