strings.Builder#
strings.Builder 是用於高效建構字串的型別:
import "strings"
var builder strings.Builder
builder.WriteString("Hello, ")
builder.WriteString("World!")
builder.WriteByte('!')
builder.WriteRune('🎉')
result := builder.String() // "Hello, World!!🎉"
fmt.Println(builder.Len()) // 目前長度為什麼使用 strings.Builder:
Go 的字串是不可變的,每次以
+串接都會建立新字串並複製內容。strings.Builder可以避免這種重複的記憶體配置與複製。// 低效做法(大量記憶體配置) s := "" for i := 0; i < 1000; i++ { s += "a" // 每次都建立新字串 } // 高效做法 var builder strings.Builder for i := 0; i < 1000; i++ { builder.WriteString("a") } s := builder.String()
內部機制#
strings.Builder 內部用 []byte 切片儲存內容:
type Builder struct {
addr *Builder // 用於檢測非法複製
buf []byte // 內部緩衝區
}預分配緩衝區
若知道最終字串的大致長度,可以預先分配:
var builder strings.Builder
builder.Grow(1000) // 預分配 1000 位元組
for i := 0; i < 100; i++ {
builder.WriteString("0123456789")
}
// 不會觸發擴容
strings.Builder不能被複製後繼續使用。複製後呼叫方法會 panic:var b1 strings.Builder b1.WriteString("hello") b2 := b1 // 複製 // b2.WriteString("world") // panic!
strings.Reader#
strings.Reader 讓字串實作 io.Reader 等介面:
reader := strings.NewReader("Hello, World!")
// 實作的介面
// io.Reader, io.ReaderAt, io.WriterTo
// io.Seeker, io.ByteScanner, io.RuneScanner
buf := make([]byte, 5)
n, _ := reader.Read(buf) // n=5, buf="Hello"
// 重置讀取位置
reader.Reset("New content")常用字串函式#
s := "Hello, World!"
// 查找
strings.Contains(s, "World") // true
strings.HasPrefix(s, "Hello") // true
strings.HasSuffix(s, "!") // true
strings.Index(s, "o") // 4
strings.LastIndex(s, "o") // 8
// 轉換
strings.ToUpper(s) // "HELLO, WORLD!"
strings.ToLower(s) // "hello, world!"
strings.TrimSpace(" hi ") // "hi"
strings.Trim(s, "!") // "Hello, World"
// 分割與連接
parts := strings.Split("a,b,c", ",") // ["a", "b", "c"]
joined := strings.Join(parts, "-") // "a-b-c"
// 替換
strings.Replace(s, "World", "Go", 1) // "Hello, Go!"
strings.ReplaceAll(s, "l", "L") // "HeLLo, WorLd!"bytes.Buffer#
bytes.Buffer 提供可讀寫的位元組緩衝區:
import "bytes"
var buf bytes.Buffer
// 寫入
buf.WriteString("Hello")
buf.WriteByte(' ')
buf.Write([]byte("World"))
// 讀取
data := buf.Bytes() // 取得內容(不消耗)
str := buf.String() // 轉為字串
line, _ := buf.ReadBytes('\n') // 讀取直到分隔符Buffer vs Builder 比較#
| 特性 | bytes.Buffer | strings.Builder |
|---|---|---|
| 用途 | 讀寫皆可 | 只寫 |
| 輸出 | []byte 或 string | 只能 string |
| 讀取 | 支援 Read、ReadByte 等 | 不支援 |
| 適用 | I/O 操作、資料處理 | 字串建構 |
- 只需要建構字串 ➡️
strings.Builder- 需要讀寫操作 ➡️
bytes.Buffer- 處理二進位資料 ➡️
bytes.Buffer