Skip to main content

Go 字串拼接常見方式

Go 中常見的字串拼接方式有五種,依效能大致排序如下:

info

效能排序(快 → 慢):
strings.Joinstrings.Builder > bytes.Buffer > + > fmt.Sprintf

+ 運算子

  • 每次拼接都會建立新字串,需重新配置並複製內容。
  • 寫法直觀,但效能較差,不適合大量或迴圈內拼接。
fmt.Print("thomas" + " test") // output:thomas test

fmt.Sprintf

  • 使用介面與反射,語法簡潔、可格式化。
  • 效能通常最差,僅適合偶爾、可讀性優先的場合。
package main

import "fmt"

func main() {
// 純字串拼接
s := fmt.Sprintf("%s%s%s", "a", "b", "c") // "abc"

// 搭配數字、布林等格式化
msg := fmt.Sprintf("user=%s, count=%d, ok=%v", "alice", 42, true)
// "user=alice, count=42, ok=true"

// 小數位數、補零等
num := fmt.Sprintf("%.2f", 3.14159) // "3.14"
code := fmt.Sprintf("%04d", 7) // "0007"

_, _, _, _ = s, msg, num, code
}
info

%s、%d、%v 是什麼

動詞意思適合型別範例輸出
%sstring,把值當字串印出string"alice"
%ddecimal integer,十進位整數int, int32, int64 等整數42
%vvalue,用預設、通用格式印出任意型別
%ffloating-point number,浮點數float32, float643.14
%tboolean,布林值booltrue
%ccharacter,字元rune'a'
%ppointer,指標*T&x
%xhexadecimal,十六進位int, int32, int64 等整數0x1234
%ooctal,八進位int, int32, int64 等整數0123
%bbinary,二進位int, int32, int64 等整數101010
%escientific notation,科學記數法float32, float641.234567e+08
%ggeneral number,通用數字格式float32, float641.234567
%qquoted string,引號字串string"hello"
%Ttype,型別任意型別int
%UUnicode code point,Unicode 碼點int32U+0041
%wwidth,寬度int10
%0padding,填補int0123
%*flag,旗標booltrue

strings.Builder

  • 內部以 []byte 緩衝區累加,最後一次轉成 string,避免多次拷貝。
  • 適合迴圈或多次拼接,為官方推薦的高效方式。
var sb strings.Builder
sb.WriteString("a")
sb.WriteString("b")
sb.WriteString("c")
ret := sb.String()

// output: abc

bytes.Buffer

  • 同樣基於 []byte 的緩衝器,可處理位元組與字串,亦可轉成 string
  • 效能略遜於 strings.Builder,若同時需要 I/O 或位元組操作時可選用。
package main

import "bytes"

func main() {
var buf bytes.Buffer

// 字串寫入
buf.WriteString("a")
buf.WriteString("b")

// 位元組寫入(適合混用 []byte 與 string)
buf.Write([]byte("c"))

// 轉成 string
ret := buf.String() // "abc"
_ = ret
}

strings.Join

  • 底層以 strings.Builder 實作,並會預先依長度呼叫 Grow 做容量規劃。
  • 已知的 []string 片段拼接非常高效,語法最簡潔。
ret := strings.Join([]string{"a", "b", "c"}, "")

綜合範例

同一組字串 ["a","b","c"] 用五種方式拼接的對照:

package main

import (
"bytes"
"fmt"
"strings"
)

func main() {
a := []string{"a", "b", "c"}

// 方式 1:+
ret1 := a[0] + a[1] + a[2]

// 方式 2:fmt.Sprintf
ret2 := fmt.Sprintf("%s%s%s", a[0], a[1], a[2])

// 方式 3:strings.Builder
var sb strings.Builder
sb.WriteString(a[0])
sb.WriteString(a[1])
sb.WriteString(a[2])
ret3 := sb.String()

// 方式 4:bytes.Buffer
buf := new(bytes.Buffer)
buf.WriteString(a[0])
buf.WriteString(a[1])
buf.WriteString(a[2])
ret4 := buf.String()

// 方式 5:strings.Join
ret5 := strings.Join(a, "")

_, _, _, _, _ = ret1, ret2, ret3, ret4, ret5
}

參考:極客兔兔《字串拼接效能及原理 | Go 語言高效能程式設計》