1. Прості струни
Для "простих" рядків (як правило, що вписується в рядок) використовується найпростіше рішення fmt.Sprintf()
та friends ( fmt.Sprint()
, fmt.Sprintln()
). Вони є аналогічними функціям без початкової S
літери, але ці Sxxx()
варіанти повертають результат string
замість того, щоб друкувати їх на стандартний вихід.
Наприклад:
s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)
Змінна s
буде ініціалізована зі значенням:
Hi, my name is Bob and I'm 23 years old.
Порада: Якщо ви просто хочете об'єднати значення різних типів, можливо, вам не доведеться автоматично використовувати Sprintf()
(для чого потрібен рядок формату), як Sprint()
саме це. Дивіться цей приклад:
i := 23
s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]"
Для об'єднання лише string
s, ви можете також використовувати strings.Join()
там, де ви можете вказати спеціальний роздільник string
(розмістити між рядками для з'єднання).
Спробуйте це на майданчику Go .
2. Складні рядки (документи)
Якщо рядок, яку ви намагаєтеся створити, є більш складною (наприклад, багаторядкове повідомлення електронної пошти), fmt.Sprintf()
стає менш читабельною та менш ефективною (особливо, якщо вам доведеться це робити багато разів).
Для цього стандартна бібліотека надає пакети text/template
та html/template
. Ці пакети реалізують керовані даними шаблони для отримання текстового виводу. html/template
призначений для створення вихідного HTML-коду, захищеного від введення коду. Він надає той самий інтерфейс, що і пакет, text/template
і його слід використовувати замість text/template
кожного разу, коли вихідний текст є HTML.
Використання template
пакунків, в основному, вимагає надати статичний шаблон у вигляді string
значення (яке може походити з файлу; в цьому випадку ви надаєте лише ім'я файлу), який може містити статичний текст, і дії, які обробляються та виконуються, коли двигун обробляє шаблон і генерує вихід.
Ви можете надати параметри, які включені / заміщені в статичний шаблон і які можуть керувати процесом генерації виводу. Типовою формою таких параметрів є struct
s та map
значення, які можуть бути вкладені.
Приклад:
Наприклад, скажімо, що ви хочете генерувати електронні повідомлення, які виглядають приблизно так:
Hi [name]!
Your account is ready, your user name is: [user-name]
You have the following roles assigned:
[role#1], [role#2], ... [role#n]
Для створення таких тел повідомлень електронної пошти ви можете використовувати такий статичний шаблон:
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}}
`
І надайте такі дані для його виконання:
data := map[string]interface{}{
"Name": "Bob",
"UserName": "bob92",
"Roles": []string{"dbteam", "uiteam", "tester"},
}
Як правило, вихідні шаблони записуються в an io.Writer
, тому якщо ви хочете результат як a string
, створіть і запишіть у a bytes.Buffer
(який реалізує io.Writer
). Виконання шаблону та отримання результату як 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()
Це призведе до очікуваного випуску:
Hi Bob!
Your account is ready, your user name is: bob92
You have the following roles assigned:
dbteam, uiteam, tester
Спробуйте це на майданчику Go .
Відзначимо також , що Go 1.10 новіше, швидше, більш спеціалізовані альтернатива доступна , bytes.Buffer
яка є: strings.Builder
. Використання дуже схоже:
builder := &strings.Builder{}
if err := t.Execute(builder, data); err != nil {
panic(err)
}
s := builder.String()
Спробуйте це на майданчику Go .
Примітка. Ви також можете відобразити результат виконання шаблону, якщо ви вказали os.Stdout
в якості цілі (яка також реалізується io.Writer
):
t := template.Must(template.New("email").Parse(emailTmpl))
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
Це запише результат безпосередньо в os.Stdout
. Спробуйте це на майданчику Go .