Sformatować ciąg Go bez drukowania?

cze 28, 2021
admin

Proste łańcuchy

Dla „prostych” łańcuchów (zwykle to, co mieści się w wierszu) najprostszym rozwiązaniem jest użycie funkcji fmt.Sprintf() i jej przyjaciół (fmt.Sprint(), fmt.Sprintln()). Są one analogiczne do funkcji bez początkowej litery S, ale te warianty Sxxx() zwracają wynik jako string zamiast wypisywać go 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 tylko konkatenować wartości różnych typów, możesz nie potrzebować automatycznie używać Sprintf() (który wymaga łańcucha formatu), ponieważ Sprint() robi dokładnie to. Zobacz ten przykład:

i := 23s := fmt.Sprint("") // s will be ""

Do konkatenacji tylko strings, możesz również użyć strings.Join(), gdzie możesz określić niestandardowy separator string (do umieszczenia między ciągami do połączenia).

Spróbuj tego na Go Playground.

Złożone ciągi (dokumenty)

Jeśli ciąg, który próbujesz utworzyć, jest bardziej złożony (np. wielowierszowa wiadomość e-mail), fmt.Sprintf() staje się mniej czytelny i mniej wydajny (zwłaszcza jeśli musisz to robić wiele razy).

Do tego celu biblioteka standardowa udostępnia pakiety text/template i html/template. Pakiety te implementują oparte na danych szablony do generowania tekstowych danych wyjściowych. html/template służy do generowania danych wyjściowych HTML bezpiecznych 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żywanie pakietów template w zasadzie wymaga dostarczenia statycznego szablonu w postaci wartości string (która może pochodzić z pliku, w którym to przypadku podajesz tylko nazwę pliku), który może zawierać statyczny tekst, oraz akcji, które są przetwarzane i wykonywane, gdy silnik przetwarza szablon i generuje wyjście.

Możesz dostarczyć parametry, które są zawarte/zastąpione w statycznym szablonie i które mogą kontrolować proces generowania danych wyjściowych. Typową formą takich parametrów są wartości structs i map, które mogą być zagnieżdżone.

Przykład:

Na przykład powiedzmy, że chcesz wygenerować wiadomości e-mail, które wyglądają tak:

Hi !Your account is ready, your user name is: You have the following roles assigned:, , ... 

Aby wygenerować takie ciała wiadomości e-mail, mógłbyś 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 dostarczyć dane jak poniżej do jego wykonania:

data := mapinterface{}{ "Name": "Bob", "UserName": "bob92", "Roles": string{"dbteam", "uiteam", "tester"},}

Normalnie dane wyjściowe szablonów są zapisywane do io.Writer, więc jeśli chcesz uzyskać 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()

To spowoduje oczekiwane wyjście:

Hi Bob!Your account is ready, your user name is: bob92You have the following roles assigned:dbteam, uiteam, tester

Wypróbuj to na Go Playground.

Zauważ również, że od Go 1.10 dostępna jest nowsza, szybsza, bardziej wyspecjalizowana alternatywa dla bytes.Buffer, która jest: strings.Builder. Użycie jest bardzo podobne:

builder := &strings.Builder{}if err := t.Execute(builder, data); err != nil { panic(err)}s := builder.String()

Spróbuj tego na Go 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)}

To zapisze wynik bezpośrednio do os.Stdout. Wypróbuj to na Go Playground.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.