Formatować ciąg Go bez drukowania?
Czy istnieje prosty sposób sformatowania łańcucha w Go bez drukowania łańcucha?
Potrafię:
bar := "bar"
fmt.Printf("foo: %s", bar)
Ale chcę, aby sformatowany łańcuch został zwrócony, a nie wydrukowany, aby móc dalej nim manipulować.
Mógłbym też zrobić coś takiego:
s := "foo: " + bar
Ale staje się to trudne do odczytania, gdy ciąg formatowania jest złożony i kłopotliwe, gdy jedna lub wiele części nie jest ciągami i musi być przekonwertowana jako pierwsza, jak
i := 25
s := "foo: " + strconv.Itoa(i)
Jestem bardzo Nowy, aby przejść - moje pochodzenie jest w Ruby, gdzie jest to proste. Czy jest na to prostszy sposób?
4 answers
Tutaj również {[3] } jest wykorzystanie go w samouczku, " a Tour of Go."
return fmt.Sprintf("at %v, %s", e.When, e.What)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-10 05:31:38
1. Struny proste
Dla" prostych " ciągów (typowo tego, co pasuje do linii) najprostszym rozwiązaniem jest użycie fmt.Sprintf()
i przyjaciele (fmt.Sprint()
, fmt.Sprintln()
). Są one analogiczne do funkcji bez litery starter S
, ale te warianty Sxxx()
zwracają wynik jako string
zamiast drukować je na standardowym wyjściu.
Na przykład:
s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)
Zmienna s
zostanie zainicjowana wartość:
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()
(która wymaga ciągu formatującego), ponieważ Sprint()
robi dokładnie to. Zobacz ten przykład:
i := 23
s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]"
Do łączenia tylko string
s, można również użyć strings.Join()
gdzie można określić niestandardowy separator string
(który ma być umieszczony pomiędzy ciągami znaków do połączenia).
Spróbuj tego na Go Playground .
2. Struny złożone (dokumenty)
Jeśli ciąg znaków, 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).
W tym celu biblioteka standardowa udostępnia Pakiety text/template
oraz html/template
. Pakiety te implementują szablony oparte na danych do generowania danych wyjściowych. {[24] } jest do generowania wyjścia HTML bezpiecznego przed wtryskiem kodu. Zapewnia ten sam interfejs, co pakiet text/template
i powinien być używany zamiast text/template
, gdy wyjściem jest HTML.
Używanie pakietów template
zasadniczo wymaga podania 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 akcje, które są przetwarzane i wykonywane, gdy silnik przetwarza szablon i generuje wyjście.
Możesz podać parametry, które są zawarte/podstawione w szablonie statycznym i które mogą sterować procesem generowania danych wyjściowych. Typową formą takich parametrów są wartości struct
s i map
, które mogą być zagnieżdżone.
Przykład:
Na przykład powiedzmy, że chcesz generować wiadomości e-mail, które wyglądają 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ć treść wiadomości e-mail w ten sposób, możesz użyć następującego statycznego szablonu:
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}}
`
I podaj takie dane do jego wykonania:
data := map[string]interface{}{
"Name": "Bob",
"UserName": "bob92",
"Roles": []string{"dbteam", "uiteam", "tester"},
}
Normalnie wyjście z szablony są pisane do io.Writer
, więc jeśli chcesz, aby wynik był string
, Utwórz i napisz do bytes.Buffer
(która 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
Spróbuj na Go Playground .
Należy również zauważyć, że od wersji 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)
}
Wynik zostanie zapisany bezpośrednio do os.Stdout
. Spróbuj tego na Go Playground .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-21 06:05:26
Fmt.Funkcja SprintF zwraca łańcuch znaków i można go sformatować w taki sam sposób, jak w przypadku fmt.PrintF
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 06:47:31
W Twoim przypadku, musisz użyć Sprintf () dla formatu string.
func Sprintf(format string, a ...interface{}) string
Sprintf formatuje zgodnie ze specyfikacją formatu i zwraca wynikowy ciąg znaków.
s := fmt.Sprintf("Good Morning, This is %s and I'm living here from last %d years ", "John", 20)
Twój wynik będzie:
Dzień dobry, Tu John i mieszkam tu od 20 lat.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 03:14:16