1. Chuỗi đơn giản
Đối với các chuỗi "đơn giản" (thường là những gì phù hợp với một dòng), giải pháp đơn giản nhất là sử dụng fmt.Sprintf()
và bạn bè ( fmt.Sprint()
, fmt.Sprintln()
). Chúng tương tự như các hàm không có S
chữ cái khởi động , nhưng các Sxxx()
biến thể này trả về kết quả là mộtstring
thay vì in chúng ra đầu ra tiêu chuẩn.
Ví dụ:
s := fmt.Sprintf("Hi, my name is %s and I'm %d years old.", "Bob", 23)
Biến s
sẽ được khởi tạo với giá trị:
Hi, my name is Bob and I'm 23 years old.
Mẹo: Nếu bạn chỉ muốn nối các giá trị của các loại khác nhau, bạn có thể không cần tự động sử dụng Sprintf()
(yêu cầu một chuỗi định dạng) như Sprint()
chính xác điều này. Xem ví dụ này:
i := 23
s := fmt.Sprint("[age:", i, "]") // s will be "[age:23]"
Để chỉ ghép nối string
s, bạn cũng có thể sử dụng strings.Join()
nơi bạn có thể chỉ định một dấu tách tùy chỉnh string
(được đặt giữa các chuỗi để nối).
Hãy thử những thứ này trên Sân chơi Go .
2. Chuỗi phức (tài liệu)
Nếu chuỗi bạn đang cố tạo phức tạp hơn (ví dụ: thư email nhiều dòng), fmt.Sprintf()
sẽ trở nên ít đọc hơn và kém hiệu quả hơn (đặc biệt là nếu bạn phải làm điều này nhiều lần).
Đối với điều này, thư viện tiêu chuẩn cung cấp các gói text/template
và html/template
. Các gói này triển khai các mẫu dựa trên dữ liệu để tạo đầu ra văn bản. html/template
là để tạo đầu ra HTML an toàn chống lại việc tiêm mã. Nó cung cấp giao diện giống như gói text/template
và nên được sử dụng thay vìtext/template
bất cứ khi nào đầu ra là HTML.
Việc sử dụng các template
gói về cơ bản đòi hỏi bạn phải cung cấp một mẫu tĩnh ở dạngstring
giá trị (có thể bắt nguồn từ một tệp trong trường hợp bạn chỉ cung cấp tên tệp) có thể chứa văn bản tĩnh và các hành động được xử lý và thực thi khi công cụ xử lý mẫu và tạo đầu ra.
Bạn có thể cung cấp các tham số được bao gồm / thay thế trong mẫu tĩnh và có thể kiểm soát quá trình tạo đầu ra. Dạng điển hình của các tham số như vậy là struct
s và map
các giá trị có thể được lồng vào nhau.
Thí dụ:
Ví dụ: giả sử bạn muốn tạo thư email giống như thế này:
Hi [name]!
Your account is ready, your user name is: [user-name]
You have the following roles assigned:
[role#1], [role#2], ... [role#n]
Để tạo các nội dung thư email như thế này, bạn có thể sử dụng mẫu tĩnh sau:
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}}
`
Và cung cấp dữ liệu như thế này để thực hiện nó:
data := map[string]interface{}{
"Name": "Bob",
"UserName": "bob92",
"Roles": []string{"dbteam", "uiteam", "tester"},
}
Thông thường đầu ra của các mẫu được ghi vào một io.Writer
, vì vậy nếu bạn muốn kết quả là a string
, hãy tạo và ghi vào một bytes.Buffer
(thực hiện io.Writer
). Thực hiện mẫu và nhận kết quả là 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()
Điều này sẽ dẫn đến đầu ra dự kiến:
Hi Bob!
Your account is ready, your user name is: bob92
You have the following roles assigned:
dbteam, uiteam, tester
Hãy thử nó trên Sân chơi Go .
Cũng lưu ý rằng kể từ Go 1.10, một lựa chọn mới hơn, nhanh hơn, chuyên dụng hơn có sẵn bytes.Buffer
là : strings.Builder
. Cách sử dụng rất giống nhau:
builder := &strings.Builder{}
if err := t.Execute(builder, data); err != nil {
panic(err)
}
s := builder.String()
Hãy thử cái này trên Sân chơi Go .
Lưu ý: bạn cũng có thể hiển thị kết quả thực hiện mẫu nếu bạn cung cấp os.Stdout
làm mục tiêu (cũng thực hiện io.Writer
):
t := template.Must(template.New("email").Parse(emailTmpl))
if err := t.Execute(os.Stdout, data); err != nil {
panic(err)
}
Điều này sẽ viết kết quả trực tiếp đến os.Stdout
. Hãy thử điều này trên Sân chơi Go .