Golang strconv.AppendQuoteRune
最后修改于 2025 年 4 月 20 日
本教程将介绍如何在 Go 中使用 `strconv.AppendQuoteRune` 函数。我们将通过实际示例涵盖 rune 引用的基础知识。
`strconv.AppendQuoteRune` 函数将单个引用的 rune 表示形式附加到字节切片。它对于高效的字符串构建非常有用。
该函数会处理特殊字符的转义,并返回扩展后的字节切片。与字符串拼接相比,它在构建带引号的输出时效率更高。
基本的 strconv.AppendQuoteRune 示例
`strconv.AppendQuoteRune` 最简单的用法是将一个带引号的 rune 附加到字节切片。这里我们展示了基本用法。
package main import ( "fmt" "strconv" ) func main() { buf := []byte("Rune: ") buf = strconv.AppendQuoteRune(buf, 'A') fmt.Println(string(buf)) }
我们从一个包含 "Rune: " 的字节切片开始。我们向其中附加一个带引号的 'A' rune。输出显示了转换回字符串的组合结果。
附加特殊字符
`strconv.AppendQuoteRune` 会自动转义特殊字符。此示例展示了它如何处理各种 rune。
package main import ( "fmt" "strconv" ) func main() { buf := []byte("Quoted: ") runes := []rune{'\n', '\t', '\'', '\\', '字'} for _, r := range runes { buf = strconv.AppendQuoteRune(buf, r) buf = append(buf, ' ') } fmt.Println(string(buf)) }
我们将几个特殊 rune 附加到一个缓冲区中。该函数会正确转义换行符、制表符、引号和反斜杠。非 ASCII rune 也会被处理。
构建带引号的 Rune 列表
此示例演示了如何在循环中使用 `AppendQuoteRune` 高效地构建带引号的 rune 列表。
package main import ( "fmt" "strconv" ) func main() { buf := []byte("Runes: [") runes := []rune{'a', 'b', 'c', '☺', '世'} for i, r := range runes { if i > 0 { buf = append(buf, ',', ' ') } buf = strconv.AppendQuoteRune(buf, r) } buf = append(buf, ']') fmt.Println(string(buf)) }
我们构建了一个逗号分隔的带引号 rune 列表。该函数高效地将每个带引号的 rune 附加到缓冲区,而无需创建中间字符串。
与 QuoteRune 比较
此示例将 `AppendQuoteRune` 与 `QuoteRune` 进行比较,以展示 append 版本的性能优势。
package main import ( "fmt" "strconv" "strings" ) func main() { // Using QuoteRune (less efficient) var builder strings.Builder builder.WriteString("Using QuoteRune: ") builder.WriteString(strconv.QuoteRune('X')) fmt.Println(builder.String()) // Using AppendQuoteRune (more efficient) buf := []byte("Using AppendQuoteRune: ") buf = strconv.AppendQuoteRune(buf, 'X') fmt.Println(string(buf)) }
在增量构建输出时,`AppendQuoteRune` 更高效。它避免了像 `QuoteRune` 那样创建中间字符串对象。
附加到现有 JSON
这个实际示例展示了在构建带有带引号 rune 值的 JSON 输出时使用 `AppendQuoteRune`。
package main import ( "fmt" "strconv" ) func main() { buf := []byte(`{"symbols": [`) symbols := []rune{'€', '$', '¥', '£'} for i, s := range symbols { if i > 0 { buf = append(buf, ',', ' ') } buf = strconv.AppendQuoteRune(buf, s) } buf = append(buf, ']', '}') fmt.Println(string(buf)) }
我们构造了一个带引号货币符号的 JSON 数组。该函数确保每个 rune 在 JSON 输出中都被正确引用和转义。
处理无效的 UTF-8
此示例演示了 `AppendQuoteRune` 如何通过正确转义来处理无效的 UTF-8 rune。
package main import ( "fmt" "strconv" ) func main() { buf := []byte("Invalid: ") // Invalid UTF-8 sequence invalidRune := rune(0xDC00) // Lone surrogate buf = strconv.AppendQuoteRune(buf, invalidRune) fmt.Println(string(buf)) }
该函数使用 Go 的转义序列格式正确转义无效的 UTF-8 rune。这确保了即使输入错误,输出仍然是有效的 UTF-8。
性能基准测试
此示例将 `AppendQuoteRune` 与字符串拼接进行基准测试,以展示其性能优势。
package main import ( "fmt" "strconv" "strings" "time" ) func main() { const iterations = 100000 testRune := '世' // Benchmark AppendQuoteRune start := time.Now() buf := make([]byte, 0, iterations*6) for i := 0; i < iterations; i++ { buf = strconv.AppendQuoteRune(buf, testRune) } _ = string(buf) fmt.Println("AppendQuoteRune:", time.Since(start)) // Benchmark string concatenation start = time.Now() var s strings.Builder for i := 0; i < iterations; i++ { s.WriteString(strconv.QuoteRune(testRune)) } _ = s.String() fmt.Println("String concat:", time.Since(start)) }
对于构建大型带引号的输出,`AppendQuoteRune` 速度明显更快。它通过直接操作字节切片来避免内存分配。
来源
本教程通过实际示例,在各种场景下高效地对 rune 进行引用,介绍了 Go 中的 `strconv.AppendQuoteRune` 函数。