go语言中的字符串详解

news2024/12/27 20:15:52

目录

字符串的基本特点

1.字符串的不可变性

2.其他基本特点

字符串基本操作

1. 创建字符串

2. 获取字符串长度

3. 字符串拼接

4. 遍历字符串

5. 字符串比较

字符串常用函数

1. 判断子串

2. 查找与索引

3. 字符串替换

4. 分割与连接

5. 修剪字符串

6. 大小写转换

字符串与其他类型转换

1. 字符串转数字

2. 字符串转字节切片

3. 字节切片转字符串

4. 字符串转 Rune 切片

性能优化建议


Go 语言中,字符串是不可变的 UTF-8 编码字节序列。它提供了多种字符串操作方法和包支持,以下是 Go 中字符串操作的详细讲解。


字符串的基本特点

1.字符串的不可变性

在 Go 中,字符串一旦被创建,其内容是无法被直接修改的。这一特性源于字符串在 Go 中被设计为只读的 UTF-8 字节序列。不可变字符串避免了多线程环境下的竞态条件,字符串可以安全地在不同 Goroutines 中传递而不需要额外的同步操作。字符串不可变意味着可以缓存其哈希值或其他元数据,从而在需要多次比较时提高效率(如在 map 中用作键)。

  • 无法直接修改字符串内容 你可以通过索引访问字符串中的某个字节,但无法通过索引赋值来修改字符串内容。

    s := "hello"
    fmt.Println(s[0]) // 输出 104,对应 'h'
    
    // s[0] = 'H' // 编译错误:cannot assign to s[0]
    
  • 修改字符串会创建新的字符串 如果需要更改字符串的内容,实际上是通过创建一个新的字符串来实现的,而不是在原字符串上进行修改。

    s := "hello"
    newS := "H" + s[1:] // 创建新字符串
    fmt.Println(newS)   // 输出 "Hello"
    
  • 性能的隐性影响

    • 因为字符串不可变,每次修改字符串时都会分配新的内存来存储新字符串,频繁的字符串操作可能会导致性能问题。
    • 解决方法:对于频繁的拼接或修改操作,可以使用可变的 strings.Builder[]byte
2.其他基本特点
  1. 索引访问:可以通过索引访问字节(s[i]),但无法直接修改。
  2. 支持 Unicode:字符串是 UTF-8 编码,可以包含中文、日文等多字节字符。
  3. 零值:字符串的零值是空字符串 ""

字符串基本操作

1. 创建字符串
s1 := "Hello, World!" // 直接赋值
s2 := `这是一个
多行字符串`        // 原生字符串(支持多行,内容不转义)
2. 获取字符串长度

len() 返回字符串的字节数(注意是字节数,不是字符数)。

s := "你好"
fmt.Println(len(s)) // 输出 6,因为 "你" 和 "好" 各占 3 个字节
3. 字符串拼接

使用 +fmt.Sprintf 拼接字符串。

s1 := "Hello"
s2 := "World"
s := s1 + ", " + s2
fmt.Println(s) // 输出 "Hello, World"

s3 := fmt.Sprintf("%s, %s!", s1, s2)
fmt.Println(s3) // 输出 "Hello, World!"
4. 遍历字符串
s := "你好Go"
for i := 0; i < len(s); i++ {
    fmt.Printf("Byte %d: %x\n", i, s[i]) // 按字节遍历
}

for i, r := range s {
    fmt.Printf("Index %d: Rune %c\n", i, r) // 按字符遍历
}
5. 字符串比较
s1 := "abc"
s2 := "def"
fmt.Println(s1 == s2) // false
fmt.Println(s1 < s2)  // true,按字典序比较

字符串常用函数

Go 提供了内置的 strings 包来操作字符串。

1. 判断子串
  • strings.Contains:是否包含子串。
  • strings.HasPrefix:是否以子串开头。
  • strings.HasSuffix:是否以子串结尾。
import "strings"

s := "hello, world"
fmt.Println(strings.Contains(s, "world"))   // true
fmt.Println(strings.HasPrefix(s, "hello")) // true
fmt.Println(strings.HasSuffix(s, "d"))     // true
2. 查找与索引
  • strings.Index:返回子串首次出现的索引,未找到返回 -1。
  • strings.LastIndex:返回子串最后出现的索引。
  • strings.Count:统计子串出现的次数。
s := "go is a good language"
fmt.Println(strings.Index(s, "good"))   // 8
fmt.Println(strings.LastIndex(s, "g")) // 17
fmt.Println(strings.Count(s, "g"))     // 3
3. 字符串替换
  • strings.Replace:替换指定子串。
  • strings.ReplaceAll:替换所有子串。
s := "hello, hello, world"
s1 := strings.Replace(s, "hello", "hi", 1)  // 替换 1 次
s2 := strings.ReplaceAll(s, "hello", "hi") // 替换所有
fmt.Println(s1) // "hi, hello, world"
fmt.Println(s2) // "hi, hi, world"
4. 分割与连接
  • strings.Split:根据分隔符分割。
  • strings.Join:将字符串切片连接。
s := "a,b,c"
parts := strings.Split(s, ",")
fmt.Println(parts) // [a b c]

joined := strings.Join(parts, "-")
fmt.Println(joined) // "a-b-c"
5. 修剪字符串
  • strings.Trim:移除指定字符。
  • strings.TrimSpace:移除两端空格。
  • strings.TrimPrefixstrings.TrimSuffix:移除前缀或后缀。
s := "  hello  "
fmt.Println(strings.TrimSpace(s))        // "hello"
fmt.Println(strings.Trim(s, " h"))       // "ello"
fmt.Println(strings.TrimPrefix(s, "  ")) // "hello  "
fmt.Println(strings.TrimSuffix(s, "  ")) // "  hello"
6. 大小写转换
  • strings.ToUpper:转大写。
  • strings.ToLower:转小写。
s := "GoLang"
fmt.Println(strings.ToUpper(s)) // "GOLANG"
fmt.Println(strings.ToLower(s)) // "golang"

字符串与其他类型转换

1. 字符串转数字

使用 strconv 包。

import "strconv"

n, err := strconv.Atoi("123")
if err != nil {
    fmt.Println("转换错误")
}
fmt.Println(n) // 123

s := strconv.Itoa(456)
fmt.Println(s) // "456"
2. 字符串转字节切片
s := "hello"
b := []byte(s)
fmt.Println(b) // [104 101 108 108 111]
3. 字节切片转字符串
b := []byte{104, 101, 108, 108, 111}
s := string(b)
fmt.Println(s) // "hello"
4. 字符串转 Rune 切片
s := "你好"
r := []rune(s)
fmt.Println(r)        // [20320 22909]
fmt.Println(string(r)) // "你好"

性能优化建议

  1. 拼接大量字符串时:使用 strings.Builderbytes.Buffer,效率高于 + 拼接。
import "strings"

var builder strings.Builder
builder.WriteString("hello")
builder.WriteString(", ")
builder.WriteString("world")
fmt.Println(builder.String()) // "hello, world"
  1. 避免重复操作:对字符串多次操作时,优先考虑转换为字节切片或 rune 切片操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2266569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

esp32学习:用虫洞ESP32S3-EYE开发板快速实现USB摄像头(UVC免驱)

直接上干货&#xff1a;实现一个USB摄像头&#xff0c;免驱UVC设备。 硬件准备&#xff1a; 乐官方推荐的Cam开发板就是乐鑫带摄像头OV2604的esp32-s3-eye&#xff0c;我们虫洞esp32-s3-eye完全兼容这个板子哦&#xff0c;虫洞ESP32-S3-EYE 人脸识别 esp-cam升级 OpenCV LVGL …

CMake 构建项目并整理头文件和库文件

本文将介绍如何使用 CMake 构建项目、编译生成库文件&#xff0c;并将头文件和库文件整理到统一的目录中以便在其他项目中使用。 1. 项目结构 假设我们正在构建一个名为 rttr 的开源库&#xff0c;初始的项目结构如下&#xff1a; D:\WorkCode\Demo\rttr-master\|- src\ …

磁盘结构、访问时间、调度算法

目录 一、什么是磁盘&#xff1f; 二、磁盘分类 1、从磁头分 2、通过盘面分 三、一次磁盘读/写的时间 四、磁盘调度算法 1、先来先到服务算法FCFS 2、最短寻找时间优先SSTF 3、扫描算法&#xff08;SCAN&#xff09; 4、LOOk算法 5、循环扫描算法&#xff08;C-SCAN…

重生之我在异世界学编程之C语言:深入预处理篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一、预处理的作用与流程&#xf…

Github——网页版上传文件夹

第一步&#xff1a;创建一个新的仓库或进入已存在的仓库页面 第二步&#xff1a;点进对应的文件夹下&#xff0c;然后 点击 “Upload files” 第三步&#xff1a;将文件夹拖拽到上传区域 打开资源管理器&#xff0c;将要上传的文件夹从计算机中拖拽到上传区域。 注意&#xf…

LeetCode - Google 校招100题 第6天 回溯法(Backtracking) (8题)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144743505 LeetCode 合计最常见的 112 题: 校招100题 第1天 链表(List) (19题)校招100题 第2天 树(Tree) (21题)校招100题 第3天 动态规划(DP) (20题)

flask后端开发(2):URL与视图

目录 URL定义request获取请求参数 gitcode地址&#xff1a; https://gitcode.com/qq_43920838/flask_project.git URL定义 from flask import FlaskappFlask(__name__)app.route(/) def hello_world():return Hello World!app.route(/profile) def profile():return 我是个人…

<数据集>风力发电机损伤识别数据集<目标检测>

数据集下载链接 &#xff1c;数据集&#xff1e;风力发电机损伤识别数据集&#xff1c;目标检测&#xff1e;https://download.csdn.net/download/qq_53332949/90187097数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2527张 标注数量(xml文件个数)&#xff1a;252…

【工具推荐】MobaXterm远程终端管理工具最全攻略,涉及下载、安装、字体配置、中文汉化版、中文显示乱码和中文输入乱码、adb tab无效无法补全、Telnet/ssh使用说明、使用技巧等保姆级教程

MobaXterm远程终端管理工具史上最全攻略&#xff0c;涉及下载、安装、字体等配置、解决中文乱码、Telnet/ssh/Serial使用教程、高级功能使用技巧等。MobaXterm 是一个增强型的 Windows 终端。其为 Windows 桌面提供所有重要的远程网络终端工具&#xff08;如 SSH、X11、RDP、VN…

19、鸿蒙学习——配置HDC命令 环境变量

一、下载Command Line Tools 可参考上篇《鸿蒙学习——配置OHPM、hvigor环境变量》 二、配置hdc环境变量 hdc命令行工具用于HarmonyOS应用/元服务调试所需的工具&#xff0c;该工具存放在命令行工具自带的sdk下的toolchains目录中。为方便使用hdc命令行工具&#xff0c;请将…

Go语言及MongoDB数据库安装配置详解!

Go语言安装 首先讲一下go语言的安装&#xff0c;这部分可直接从官网下载&#xff0c;基本上一键配置的&#xff1a; 官网地址&#xff1a;All releases - The Go Programming Language 选择自己对应系统的安装包&#xff0c;这里官网提供了5种不同的包可自行下载 之后便是默认…

Linux配置ODBC连接Mysql

1、安装mysql 2、安装unixodbc odbcinst -j 查询unixodbc版本以及配置文件路径 3、安装mysql-connector-odbc ####下载 wget https://cdn.mysql.com/archives/mysql-connector-odbc-9.0/mysql-connector-odbc-9.0.0-1.el7.x86_64.rpm ####安装 rpm -ivh mysql-connector-od…

芯片Tapeout power signoff 之IR Drop Redhawk Ploc文件格式及其意义

数字IC后端工程师在芯片流程最后阶段都会使用redhawk或voltus进行设计的IR Drop功耗signoff分析。必须确保静态&#xff0c;动态ir drop都符合signoff标准。 在做redhawk ir drop分析前&#xff0c;我们需要提供一个redhawk ploc供电点坐标。 数字IC设计后端实现前期预防IR D…

数据仓库工具箱—读书笔记02(Kimball维度建模技术概述03、维度表技术基础)

Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考&#xff0c;摘录一些书中关于维度建模比较重要的思想与大家分享&#x1f923;&#x1f923;&#x1f923; 第二章前言部分作者提到&#xff1a;技术的介绍应该通过涵盖各种行业的熟悉的用例展开&#xff08;赞同…

设置首选网络类型以及调用Android框架层的隐藏API

在Android SDK中提供的framework.jar是阉割版本的&#xff0c;比如有些类标记为hide&#xff0c;这些类不会被打包到这个jar中&#xff0c;而有些只是类中的某个方法或或属性被标记为hide&#xff0c;则这些类或属性会被打包到framework.jar&#xff0c;但是我们无法调用&#…

3D几何建模引擎Parasolid功能解析

一、什么是Parasolid&#xff1f; Parasolid是由Siemens PLM Software开发的高精度精密几何建模引擎。它全面评估CAD&#xff08;计算机辅助设计&#xff09;、CAM&#xff08;计算机辅助制造&#xff09;、CAE&#xff08;计算机辅助工程&#xff09;、PLM&#xff08;产品生…

xinput1_3.dll放在哪里?当xinput1_3.dll丢失时的应对策略:详细解决方法汇总

在计算机系统的运行过程中&#xff0c;我们偶尔会遇到一些令人困扰的问题&#xff0c;其中xinput1_3.dll文件丢失就是较为常见的一种情况。这个看似不起眼的动态链接库文件&#xff0c;实则在许多软件和游戏的正常运行中发挥着至关重要的作用。一旦它丢失&#xff0c;可能会导致…

【开源免费】基于SpringBoot+Vue.JS安康旅游网站(JAVA毕业设计)

本文项目编号 T 098 &#xff0c;文末自助获取源码 \color{red}{T098&#xff0c;文末自助获取源码} T098&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

CSS(三)盒子模型

目录 Content Padding Border Margin 盒子模型计算方式 使用 box-sizing 属性控制盒子模型的计算 所有的HTML元素都可以看作像下图这样一个矩形盒子&#xff1a; 这个模型包括了四个区域&#xff1a;content&#xff08;内容区域&#xff09;、padding&#xff08;内边距…

LeetCode - Google 校招100题 第7天 序列(数据结构贪心) (15题)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144744418 相关文章: LeetCode 合计最常见的 112 题: 校招100题 第1天 链表(List) (19题)校招100题 第2天 树(Tree) (21题)校招100题 第3天 动态规划(DP) (