Go语言入门13:字符串

Keywords: #技术 #Golang #Go 入门笔记
Table of Contents

Go 语言入门基础学习笔记之 Go 语言的字符串

golang

字符串

字符

  • 定义:在 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 来构建字符串,因为它们在内部管理内存,从而减少了内存分配和复制的次数。

  1. 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,方便进行字符串构建。

  1. 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 码点。

参考课程:

  1. 8小时转职Golang工程师
  2. Go语言教程 | 菜鸟教程