Go语言入门13:字符串
Table of Contents
Go 语言入门基础学习笔记之 Go 语言的字符串
字符串
字符
- 定义:在 Go 中,字符使用
rune
类型表示,实际上是一个int32
,用于表示 Unicode 代码点。 - 声明:可以直接使用字符字面量,使用单引号包围。例如:
var c rune = 'A'
字符串(string)
- 定义:字符串是由零个或多个字节组成的不可变的序列。它是 Go 的基本数据类型。
- 声明:使用双引号
" "
包围。例如:
var s string = "Hello, World!"
- 字符串可以用双引号
" "
或反引号`
包围。 - 字符串可以包含转义字符,如
\n
表示换行,\t
表示制表符等。通过开头加r
来取消转义(与 python 一样)。 - 字符串也可以包含 Unicode 字符,如
\u0041
表示大写字母 A。
字符串基本操作
长度:可以使用 len()
函数获取字符串的字节数。
length := len(s) // 返回字节数
索引:可以通过索引访问字符串中的字符(字节)。
firstChar := s[0] // 获取第一个字节
字符到字符串:可以通过 string()
函数将 rune
转换为字符串。
s2 := string(c) // 将 rune 转换为字符串
字符串到字符:可以通过索引将字符串转换为 rune
。
char := s[0] // 获取字符串的第一个字符(字节)
字符串拼接:使用 +
运算符可以拼接字符串。
s3 := s + " How are you?"
但这种方式在循环中效率较低,因为每次连接都会创建新的字符串。更高效的方法是使用
strings.Builder
或bytes.Buffer
来构建字符串,因为它们在内部管理内存,从而减少了内存分配和复制的次数。
strings.Builder
是一个提供高效字符串拼接的类型,适用于构建字符串而不是重复的字符串连接。
// 创建 Builder 实例
var b strings.Builder
// 可以使用 `WriteString` 方法将字符串添加到 Builder 中
b.WriteString("Hello")
b.WriteString(", ")
b.WriteString("World!")
// 使用 `String()` 方法获取最终构建的字符串
result := b.String() // "Hello, World!"
// 如果需要重用同一个 Builder,可以使用 `Reset()` 方法
b.Reset() // 清空 Builder 的内容
其优点在于:1. 高效:相较于直接拼接字符串,strings.Builder
通过预分配内存来减少内存分配的数量。2. 简单易用:提供了简单的 API,方便进行字符串构建。
bytes.Buffer
是一个字节缓冲区,通常用于处理字节流,但也可以用于构建字符串。
// 创建 Buffer 实例
var buf bytes.Buffer
// 可以使用 `Write` 或 `WriteString` 方法将数据添加到 Buffer 中
buf.WriteString("Hello")
buf.Write([]byte(", "))
buf.WriteString("World!")
// 使用 `String()` 方法获取构建的字符串
result := buf.String() // "Hello, World!"
// 使用 `Reset()` 方法可以清空 Buffer 的内容
buf.Reset() // 清空 Buffer
其优点在于:1. 灵活性:bytes.Buffer
可以处理字节数据,适合需要处理原始字节流的场景。2. 高性能:适合需要频繁添加数据的场景,可以减少内存分配和复制。
实例:
package main
import (
"bytes"
"fmt"
"strings"
)
func main() {
// 使用 strings.Builder
var sb strings.Builder
sb.WriteString("Hello")
sb.WriteString(", ")
sb.WriteString("World!")
fmt.Println(sb.String()) // 输出: Hello, World!
// 使用 bytes.Buffer
var buf bytes.Buffer
buf.WriteString("Hello")
buf.Write([]byte(", "))
buf.WriteString("World!")
fmt.Println(buf.String()) // 输出: Hello, World!
}
// 输出结果
Hello, World!
Hello, World!
字符串切片:可以使用切片语法 获取字符串的子串。
sub := s[0:5] // 获取子串 "Hello"
字符串可以转换为字节切片(
[]byte
),这在处理非 UTF-8 编码的数据时非常有用。同时可以使用string(b)
将字节切片转换回字符串。
字符串遍历:使用 for
循环和 range
可以遍历字符串中的字符,注意它会正确处理 Unicode 字符。
for i, c := range s {
fmt.Printf("Index: %d, Character: %c\n", i, c)
}
使用
for
循环遍历字符串中的每个字符,但需要注意,这将按字节遍历,而不是按 Unicode 码点。因此需要使用range
,它会正确处理多字节字符。
字符串比较:可以直接使用 ==
和 !=
运算符对字符串进行比较。
if s == "Hello, World!" {
fmt.Println("Strings are equal")
}
字符串常用函数:
len(s)
:返回字符串s
的长度。strings.Contains(s, substr)
:检查字符串s
是否包含子串substr
。strings.HasPrefix(s, prefix)
和strings.HasSuffix(s, suffix)
:检查字符串s
是否以prefix
开头或以suffix
结尾。strings.Index(s, substr)
:返回子串substr
在字符串s
中首次出现的位置。strings.Join(a, sep)
:将字符串切片a
用sep
连接起来。strings.Split(s, sep)
:将字符串s
按照sep
分割成字符串切片。strings.ToLower(s)
和strings.ToUpper(s)
:将字符串s
转换为全小写或全大写。
注意点
- 字符串是不可变的,任何对字符串的修改都会生成一个新的字符串。
- 使用
len()
获取的是字节数,而不是字符数,如果字符串中包含多字节的 Unicode 字符,可能会导致混淆。 - Go 语言的字符串以 UTF-8 编码,这意味着一个 Unicode 字符可能由多个字节表示。
- 使用
rune
类型来处理多字节字符,rune
是int32
的别名,用于表示 Unicode 码点。
参考课程: