字符串基础 #
一、字符串概述 #
1.1 字符串特点 #
- 不可变:创建后不能修改
- UTF-8编码
- 双引号或反引号定义
- 值类型
二、字符串定义 #
2.1 双引号字符串 #
go
s := "Hello, World!"
fmt.Println(s)
支持转义字符:
go
s := "Hello\nWorld\t!"
fmt.Println(s)
2.2 反引号字符串 #
原始字符串,不支持转义:
go
s := `Hello
World
"引号"`
fmt.Println(s)
2.3 字符串零值 #
go
var s string
fmt.Println(s) // 空字符串
fmt.Println(s == "") // true
三、字符串不可变性 #
3.1 不能修改 #
go
s := "Hello"
s[0] = 'h' // 错误:字符串不可变
3.2 重新赋值 #
go
s := "Hello"
s = "World" // 可以重新赋值
3.3 修改需要转换 #
go
s := "Hello"
b := []byte(s)
b[0] = 'h'
s = string(b)
fmt.Println(s) // hello
四、字符串长度 #
4.1 len函数 #
返回字节数:
go
s := "Hello"
fmt.Println(len(s)) // 5
s2 := "世界"
fmt.Println(len(s2)) // 6(UTF-8编码,每个中文3字节)
4.2 字符数 #
go
s := "世界"
fmt.Println(utf8.RuneCountInString(s)) // 2
4.3 遍历字符 #
go
s := "世界"
for i, r := range s {
fmt.Printf("%d: %c\n", i, r)
}
五、UTF-8编码 #
5.1 编码规则 #
| 字符范围 | 编码长度 |
|---|---|
| ASCII (0-127) | 1字节 |
| 其他BMP字符 | 2-3字节 |
| 补充字符 | 4字节 |
5.2 中文编码 #
go
s := "中"
fmt.Println(len(s)) // 3
b := []byte(s)
fmt.Printf("%x %x %x\n", b[0], b[1], b[2]) // e4 b8 ad
5.3 rune类型 #
rune是int32别名,表示Unicode码点:
go
var r rune = '中'
fmt.Printf("%c\n", r) // 中
fmt.Printf("%U\n", r) // U+4E2D
fmt.Printf("%d\n", r) // 20013
六、字符串遍历 #
6.1 按字节遍历 #
go
s := "Hello"
for i := 0; i < len(s); i++ {
fmt.Printf("%d: %c\n", i, s[i])
}
6.2 按rune遍历 #
go
s := "世界"
for i, r := range s {
fmt.Printf("%d: %c\n", i, r)
}
6.3 转换为rune切片 #
go
s := "世界"
runes := []rune(s)
fmt.Println(len(runes)) // 2
for i, r := range runes {
fmt.Printf("%d: %c\n", i, r)
}
七、字符串连接 #
7.1 使用+号 #
go
s := "Hello" + " " + "World"
fmt.Println(s)
7.2 使用fmt.Sprintf #
go
name := "World"
s := fmt.Sprintf("Hello, %s!", name)
fmt.Println(s)
7.3 使用strings.Builder #
go
var builder strings.Builder
builder.WriteString("Hello")
builder.WriteString(" ")
builder.WriteString("World")
s := builder.String()
fmt.Println(s)
7.4 使用strings.Join #
go
parts := []string{"Hello", "World"}
s := strings.Join(parts, " ")
fmt.Println(s)
八、字符串比较 #
8.1 相等比较 #
go
s1 := "Hello"
s2 := "Hello"
fmt.Println(s1 == s2) // true
8.2 大小比较 #
go
s1 := "apple"
s2 := "banana"
fmt.Println(s1 < s2) // true(字典序)
fmt.Println(s1 > s2) // false
8.3 忽略大小写比较 #
go
import "strings"
s1 := "Hello"
s2 := "HELLO"
fmt.Println(strings.EqualFold(s1, s2)) // true
九、字符串与字节切片 #
9.1 字符串转字节切片 #
go
s := "Hello"
b := []byte(s)
fmt.Println(b) // [72 101 108 108 111]
9.2 字节切片转字符串 #
go
b := []byte{72, 101, 108, 108, 111}
s := string(b)
fmt.Println(s) // Hello
9.3 不安全转换 #
避免复制的转换:
go
import "unsafe"
func stringToBytes(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}
func bytesToString(b []byte) string {
return unsafe.String(&b[0], len(b))
}
十、实际应用 #
10.1 判断字符串是否为空 #
go
func isEmpty(s string) bool {
return s == ""
}
func isBlank(s string) bool {
return strings.TrimSpace(s) == ""
}
10.2 字符串截取 #
go
func substring(s string, start, end int) string {
runes := []rune(s)
if start < 0 {
start = 0
}
if end > len(runes) {
end = len(runes)
}
return string(runes[start:end])
}
s := "世界你好"
fmt.Println(substring(s, 0, 2)) // 世界
10.3 反转字符串 #
go
func reverse(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
fmt.Println(reverse("Hello")) // olleH
十一、总结 #
字符串要点:
| 特性 | 说明 |
|---|---|
| 定义 | 双引号或反引号 |
| 不可变 | 创建后不能修改 |
| 编码 | UTF-8 |
| 长度 | len()返回字节数 |
| 字符 | rune类型表示Unicode码点 |
关键点:
- 不可变性:字符串创建后不能修改
- UTF-8编码:Go字符串默认UTF-8
- rune类型:表示Unicode字符
- 长度计算:len()返回字节数,utf8.RuneCountInString()返回字符数
- 高效连接:使用strings.Builder
准备好学习字符串操作了吗?让我们进入下一章!
最后更新:2026-03-26