Go 语言的 string 类型是用于表示文本的基本数据类型。它不可变,创建之后不能被修改;内部按 UTF-8 编码,能容纳多种语言的字符。
声明和初始化
你可以通过多种方式来声明和初始化字符串:
go
package main
import "fmt"
func main() {
var s1 string // 声明但未初始化,默认值为空字符串 ""
var s2 string = "Hello" // 声明并初始化
s3 := "World" // 简短声明并初始化
fmt.Printf("s1: %q, s2: %s, s3: %s\n", s1, s2, s3) // s1: "", s2: Hello, s3: World
}字符串连接
可以使用加号(+)操作符连接两个字符串:
go
s2 := "Hello"
s3 := "World"
greeting := s2 + ", " + s3 + "!"
fmt.Println(greeting) // 输出: Hello, World!多行字符串
使用反引号(`)来声明多行字符串,反引号中的字符串不会进行转义,原样保留所有内容,包括换行符:
go
multiLine := `This is a
multi-line
string.`
fmt.Println(multiLine)字符串长度
使用 len 函数可以获取字符串的长度,长度指的是字节数而不是字符数:
go
greeting := "Hello, World!"
length := len(greeting)
fmt.Println("Length of greeting:", length) // 输出: Length of greeting: 13字符串索引和切片
可以通过索引访问字符串中的字节(注意是字节而不是字符):
go
greeting := "Hello, World!"
char := greeting[0]
fmt.Println("First character:", string(char)) // 输出: First character: H可以通过切片操作符获取字符串的子串:
go
greeting := "Hello, World!"
substring := greeting[0:5]
fmt.Println("Substring:", substring) // 输出: Substring: Hello字符串比较
可以使用比较操作符(==, !=, <, >, <=, >=)来比较字符串:
go
s2 := "Hello"
if s2 == "Hello" {
fmt.Println("s2 is Hello")
}字符串常用函数
Go 提供了很多字符串处理函数,这些函数在 strings 包中:
go
import (
"fmt"
"strings"
)
func main() {
s := "Hello, World!"
fmt.Println(strings.ToUpper(s)) // 转为大写: HELLO, WORLD!
fmt.Println(strings.ToLower(s)) // 转为小写: hello, world!
fmt.Println(strings.Contains(s, "Wo")) // 是否包含: true
fmt.Println(strings.ReplaceAll(s, "World", "Go")) // 替换: Hello, Go!
fmt.Println(strings.Split(s, ", ")) // 分割: [Hello World!]
}遍历字符串
可以使用 range 关键字遍历字符串中的字符:
go
s := "Hello"
for i, c := range s {
fmt.Printf("Index: %d, Character: %c\n", i, c)
}注意事项
- 不可变性:字符串一旦创建不可修改。如果需要大量拼接字符串,建议使用
strings.Builder或bytes.Buffer以提高性能。 - UTF-8 编码:Go 的字符串是 UTF-8 编码的,这意味着一个字符可能占用多个字节。遍历字符串时要小心处理多字节字符。
示例代码
下面是一个完整的示例代码,展示了字符串的声明、初始化、操作和遍历:
go
package main
import (
"fmt"
"strings"
)
func main() {
var s1 string
fmt.Printf("s1: %q\n", s1) // 输出: s1: ""
s2 := "Hello"
s3 := "World"
greeting := s2 + ", " + s3 + "!"
fmt.Println(greeting) // 输出: Hello, World!
multiLine := `This is a
multi-line
string.`
fmt.Println(multiLine)
fmt.Println("Length of greeting:", len(greeting)) // 输出: Length of greeting: 13
fmt.Println("First character:", string(greeting[0])) // 输出: First character: H
substring := greeting[0:5]
fmt.Println("Substring:", substring) // 输出: Substring: Hello
if s2 == "Hello" {
fmt.Println("s2 is Hello")
}
fmt.Println(strings.ToUpper(greeting)) // 输出: HELLO, WORLD!
fmt.Println(strings.ToLower(greeting)) // 输出: hello, world!
fmt.Println(strings.Contains(greeting, "Wo")) // 输出: true
fmt.Println(strings.ReplaceAll(greeting, "World", "Go")) // 输出: Hello, Go!
fmt.Println(strings.Split(greeting, ", ")) // 输出: [Hello World!]
for i, c := range greeting {
fmt.Printf("Index: %d, Character: %c\n", i, c)
}
}跑一遍这个例子能看清三件事:len 数的是字节,range 遍历取的是字符,切片 [0:5] 按字节切。碰到多字节字符时,这三个结果各不相同。