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 函数。