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