跳到主要内容

strings / bytes / strconv

问题

Go 中字符串操作有哪些常用函数?strings 和 bytes 包有什么区别?

答案

strings 包

import "strings"

strings.Contains("hello world", "world") // true
strings.HasPrefix("hello", "he") // true
strings.HasSuffix("hello", "lo") // true
strings.Index("hello", "ll") // 2
strings.Count("hello", "l") // 2
strings.Replace("hello", "l", "L", -1) // "heLLo"(-1=全部替换)
strings.ToUpper("hello") // "HELLO"
strings.ToLower("HELLO") // "hello"
strings.TrimSpace(" hello ") // "hello"
strings.Trim("##hello##", "#") // "hello"
strings.Split("a,b,c", ",") // ["a", "b", "c"]
strings.Join([]string{"a", "b"}, ",") // "a,b"
strings.Repeat("ha", 3) // "hahaha"
strings.EqualFold("Go", "go") // true(忽略大小写)

// strings.Builder:高性能字符串拼接
var b strings.Builder
b.WriteString("hello")
b.WriteString(" world")
s := b.String() // "hello world"

// strings.NewReader:从字符串创建 io.Reader
r := strings.NewReader("hello")

bytes 包

bytes 包与 strings 类似,但操作 []byte

import "bytes"

bytes.Contains([]byte("hello"), []byte("ell")) // true
bytes.Equal(a, b) // 比较
bytes.Join([][]byte{a, b}, []byte(",")) // 拼接

// bytes.Buffer:可读可写的缓冲区
var buf bytes.Buffer
buf.WriteString("hello")
buf.Write([]byte(" world"))
data := buf.Bytes() // []byte
str := buf.String() // string

strconv 包

import "strconv"

// int <-> string
strconv.Itoa(42) // "42"
strconv.Atoi("42") // 42, nil

// 更灵活的转换
strconv.FormatInt(255, 16) // "ff"(十六进制)
strconv.ParseInt("ff", 16, 64) // 255

// float <-> string
strconv.FormatFloat(3.14, 'f', 2, 64) // "3.14"
strconv.ParseFloat("3.14", 64) // 3.14

// bool <-> string
strconv.FormatBool(true) // "true"
strconv.ParseBool("true") // true

strings.Builder vs bytes.Buffer vs +

方式性能特点
+ 拼接最慢每次创建新字符串
fmt.Sprintf较慢方便但有反射开销
bytes.Buffer可读可写,更通用
strings.Builder最快专为字符串拼接优化

常见面试问题

Q1: strings.Builder 为什么比 + 快?

答案+ 每次拼接都分配新字符串并复制,O(n2)O(n^2)strings.Builder 内部维护一个 []byte,按需扩容,最后一次性转换为 string(通过 unsafe 零拷贝)。

Q2: strconv.Atoi 和 fmt.Sscanf 哪个好?

答案strconv.Atoi 更好——无反射开销、无内存分配,性能约是 fmt.Sscanf 的 10 倍。

相关链接