Golang strconv.AppendQuote
最后修改于 2025 年 4 月 20 日
本教程讲解如何在 Go 中使用 strconv.AppendQuote
函数。我们将通过实际示例讲解字符串引用的基础知识,并演示如何追加带引用的字符串。
strconv.AppendQuote
函数将一个双引号引起来的 Go 字符串字面量追加到一个字节切片。它会根据 Go 的语法规则正确地转义特殊字符。
此函数对于构建需要包含带引用字符串的字节切片非常有用。它比先创建字符串然后转换为字节更有效率。
基本的 strconv.AppendQuote 示例
strconv.AppendQuote
最简单的用法是将一个带引用的字符串追加到字节切片。这里我们演示了对不同字符串输入的基本用法。
package main import ( "fmt" "strconv" ) func main() { buf := []byte("Prefix: ") buf = strconv.AppendQuote(buf, "Hello, World!") fmt.Println(string(buf)) buf = []byte{} buf = strconv.AppendQuote(buf, "Go\"lang") fmt.Println(string(buf)) }
我们从一个包含“Prefix: ”的字节切片开始,然后追加一个带引用的字符串。第二个示例展示了如何引用一个包含双引号字符的字符串。
追加多个带引用的字符串
strconv.AppendQuote
可以多次使用来构建复杂的字节切片。此示例演示了如何构建一个类似 JSON 的结构。
package main import ( "fmt" "strconv" ) func main() { buf := []byte("{") buf = append(buf, '\n') buf = append(buf, " name: "...) buf = strconv.AppendQuote(buf, "John Doe") buf = append(buf, ',', '\n') buf = append(buf, " email: "...) buf = strconv.AppendQuote(buf, "john@example.com") buf = append(buf, '\n', '}') fmt.Println(string(buf)) }
我们通过交替使用 AppendQuote
和常规追加操作来构建结构化的字节切片。结果是一个格式正确的带引用的输出。
处理特殊字符
strconv.AppendQuote
会自动转义特殊字符。此示例展示了它如何处理输入字符串中的各种特殊情况。
package main import ( "fmt" "strconv" ) func main() { tests := []string{ "Line\nBreak", "Tab\tHere", "Back\\Slash", "Quote\"Mark", "Non-ASCII: 日本語", } for _, s := range tests { buf := strconv.AppendQuote([]byte{}, s) fmt.Printf("%-20s → %s\n", s, string(buf)) } }
该函数会正确转义换行符、制表符、反斜杠和引号。它还会正确处理非 ASCII 字符,将它们按原样包含在输出中。
性能比较
此示例比较了 AppendQuote
与创建带引用字符串的替代方法的性能。
package main import ( "fmt" "strconv" "strings" "time" ) func main() { const iterations = 1000000 testStr := "The quick brown fox jumps over the lazy dog" // Benchmark AppendQuote start := time.Now() buf := make([]byte, 0, 100) for i := 0; i < iterations; i++ { buf = strconv.AppendQuote(buf[:0], testStr) } fmt.Println("AppendQuote duration:", time.Since(start)) // Benchmark Quote + conversion start = time.Now() for i := 0; i < iterations; i++ { _ = []byte(strconv.Quote(testStr)) } fmt.Println("Quote+conversion duration:", time.Since(start)) // Benchmark fmt.Sprintf start = time.Now() for i := 0; i < iterations; i++ { _ = []byte(fmt.Sprintf("%q", testStr)) } fmt.Println("fmt.Sprintf duration:", time.Since(start)) }
在直接构建字节切片时,AppendQuote
比替代方法快得多。它避免了中间的字符串分配和转换。
构建 CSV 数据
这个实际示例展示了如何使用 AppendQuote
来构建 CSV 数据,并正确引用包含特殊字符的字段。
package main import ( "fmt" "strconv" ) func main() { records := [][]string{ {"Name", "Email", "Phone"}, {"John Doe", "john@example.com", "123-456-7890"}, {"Jane \"The Boss\" Smith", "jane@example.com", "987-654-3210"}, {"Bob, Jr.", "bob@example.com", "555-123-4567"}, } var csvData []byte for _, record := range records { for i, field := range record { if i > 0 { csvData = append(csvData, ',') } csvData = strconv.AppendQuote(csvData, field) } csvData = append(csvData, '\n') } fmt.Println(string(csvData)) }
我们通过正确引用每个字段来构建 CSV 文件。包含逗号或引号的字段会自动转义,从而生成有效的 CSV 输出。
自定义 JSON 编码
此示例演示了一个简化的 JSON 编码器,它在 JSON 输出中使用 AppendQuote
来处理字符串值。
package main import ( "fmt" "strconv" ) func main() { data := map[string]string{ "name": "Alice", "address": "123 \"Main\" St", "city": "New York", } var jsonBuf []byte jsonBuf = append(jsonBuf, '{', '\n') first := true for k, v := range data { if !first { jsonBuf = append(jsonBuf, ',', '\n') } first = false jsonBuf = strconv.AppendQuote(jsonBuf, k) jsonBuf = append(jsonBuf, ':', ' ') jsonBuf = strconv.AppendQuote(jsonBuf, v) } jsonBuf = append(jsonBuf, '\n', '}') fmt.Println(string(jsonBuf)) }
我们通过引用键和值来构建 JSON 对象。输入字符串中的特殊字符会在 JSON 输出中被正确转义。
追加到现有缓冲区
此示例展示了在性能敏感的代码中重复调用 AppendQuote
时如何有效地重用缓冲区。
package main import ( "fmt" "strconv" ) func main() { messages := []string{ "First message", "Second message with \"quotes\"", "Third message\nwith newline", } // Pre-allocate buffer with capacity buf := make([]byte, 0, 256) for _, msg := range messages { // Reset buffer length while keeping capacity buf = buf[:0] buf = append(buf, "-> "...) buf = strconv.AppendQuote(buf, msg) buf = append(buf, '\n') fmt.Print(string(buf)) } }
我们在每次迭代中重用相同的缓冲区,重置其长度但保留分配的容量。这减少了紧密循环中的内存分配。
来源
本教程通过构建包含带引用字符串的字节切片的实际示例,介绍了 Go 中的 strconv.AppendQuote
函数。