Golang 字符串
目录
- 1. Golang 字符串
- 1.1. 基础概念
- 1.2. 字符串编码
- 1.3. 遍历字符串
- 1.4. 类型转换
- 1.5. 总结
- 1.6. String Concatenation (字符串连接)
- 1.6.1. Using the `+` operator
- 1.6.2. Using the `+=` operator
- 1.6.3. Using the Join method
- 1.6.4. Using Sprintf method
- 1.6.5. Using Go string Builder method
- 1.6.6. Using the Bytes buffer method
- 1.7. String Comparison
- 1.7.1. Using Comparison operators
- 1.7.2. Using Compare method
- 1.7.3. Using strings EqualFold
- 1.8. String Manipulation and utility methods
- 1.8.1. ToLower, ToUpper and Title functions
- 1.8.2. Contains and ContainsAny functions
- 1.8.3. Split and SplitAfter functions
- 1.8.4. Repeat and Fields functions
1. Golang 字符串
1.1. 基础概念
ASCII 是英文"American Standard Code for Information Interchange"的缩写,中文译为美国信息交换标准代码,它是由美国国家标准学会 (ANSI) 制定的单字节字符编码方案,它使用单个字节 (byte) 的二进制数来编码一个字符。
Unicode 编码规范为世界上现存的所有自然语言中的每一个字符,都设定了一个唯一的二进制编码。它以 ASCII 编码集为出发点,并突破了 ASCII 只能对拉丁字母进行编码的限制。Unicode 编码规范通常使用十六进制表示法来表示 Unicode 代码的整数值,并提供了三种不同的编码格式,即:UTF-8、UTF-16 和 UTF-32。
UTF-8 以 8 个比特(一个字节)作为一个编码单元,它是一种可变宽的编码方案,它会用一个或多个字节的二进制数来表示某个字符,最多使用四个字节。对于一个英文字符,它仅用一个字节的二进制数就可以表示,而对于一个中文字符,它需要使用三个字节才能够表示。rune 是 Go 语言特有的一个基本数据类型,它的一个值就代表一个 Unicode 字符,比如’吕’、‘M’。一个 rune 类型的值会由四个字节宽度的空间来存储,它的存储空间总是能够存下一个 UTF-8 编码值。
1.2. 字符串编码
一个 rune 类型的值在底层其实就是一个 UTF-8 编码值,前者是(便于我们人类理解的)外部展现,后者是(便于计算机系统理解的)内在表达,请看下面代码:
func main() {str := "Go 爱好者"fmt.Printf("The string: %q\n", str)fmt.Printf("runes(char): %q\n", []rune(str)) //['G' 'o' '爱' '好' '者']fmt.Printf("runes(hex): %x\n", []rune(str)) //[47 6f 7231 597d 8005]fmt.Printf("bytes(hex): [% x]\n", []byte(str)) //[47 6f e7 88 b1 e5 a5 bd e8 80 85]
}
对于第 3 行输出,前面解释的比较清楚,就不赘述。对于第 4 行输出,就是通过 UTF-8 编码,3 个字节的 16 进制展现。第 5 行输出,把每个字符的 UTF-8 编码值都拆成相应的字节序列。
一句话总结一下:一个 string 类型的值在底层就是一个能够表达若干个 UTF-8 编码值的字节序列。
1.3. 遍历字符串
range 遍历:
func main() {str := "Go 爱好者"fmt.Printf("range 遍历:\n")for i, c := range str {fmt.Printf("%d: %q [% x]\n", i, c, []byte(string(c)))}fmt.Printf("for 遍历:\n")for i := 0; i < len(str); i++ {fmt.Printf("%d: [%c] [%x]\n", i, str[i], str[i])}
}
输出如下:
range 遍历:
0: 'G' [47]
1: 'o' [6f]
2: ' ' [20]
3: '爱' [e7 88 b1]
6: '好' [e5 a5 bd]
9: '者' [e8 80 85]
for 遍历:
0: [G] [47]
1: [o] [6f]
2: [ ] [20]
3: [ç] [e7]
4: [ˆ] [88]
5: [±] [b1]
6: [å] [e5]
7: [¥] [a5]
8: [½] [bd]
9: [è] [e8]
10: [€] [80]
11: [
] [85]
由此可以看出,通过 range 方式的遍历,是以 rune 为单位,但是相邻字符的索引值并不一定是连续的;通过 for 方式的遍历,是以 byte 为单位。
1.4. 类型转换
字符串是不能直接修改的,如果需要修改,需要转换为可变类型 ([]rune 和 []bype), 待修改完后再转换回来。但不管如何转换,都需要重新分配内存,并复制数据。
func main() {str := "hello, world!"bs := []byte(str) // string 转 bytestr2 := string(bs) // byte 转 stringrs := []rune(str) // string 转 runestr3 := string(rs) // rune 转 string
}
前面已经讲解 string、rune 和 byte 的区别和联系,这里再理解他们的转换,是不是就轻松很多了呢。
1.5. 总结
Go 语言的代码是由 Unicode 字符组成的,它们都必须由 Unicode 编码规范中的 UTF-8 编码格式进行编码并存储,Unicode 编码规范中的编码格式定义的是:字符与字节序列之间的转换方式。其中的 UTF-8 是一种可变宽的编码方案,它会用一个或多个字节的二进制数来表示某个字符,最多使用四个字节。Go 语言中的一个 string 类型值会由若干个 Unicode 字符组成,每个 Unicode 字符都可以由一个 rune 类型的值来承载。这些字符在底层都会被转换为 UTF-8 编码值,而这些 UTF-8 编码值又会以字节序列的形式表达和存储。因此,一个 string 类型的值在底层就是一个能够表达若干个 UTF-8 编码值的字节序列。对于通过 for range 方式遍历字符串,会先把被遍历的字符串值拆成一个字节序列,然后再试图找出这个字节序列中包含的每一个 UTF-8 编码值,或者说每一个 Unicode 字符。相邻的 Unicode 字符的索引值并不一定是连续的,这取决于前一个 Unicode 字符是否为单字节字符,一旦我们清楚了这些内在机制就不会再困惑了。对于 Go 语言来说,Unicode 编码规范和 UTF-8 编码格式算是基础之一,我们应该了解到它们对 Go 语言的重要性,这对于正确理解 Go 语言中的相关数据类型以及日后的相关程序编写都会很有好处。
1.6. String Concatenation (字符串连接)
1.6.1. Using the + operator
package mainimport ("fmt"
)func main() {s1 := "Go"s2 := "Programming"s3 := "Language"s := s1 + s2 + s3fmt.Println(s)
}
$ go run concatenate.goGoProgrammingLanguage
1.6.2. Using the += operator
p := "Story"
p += "Book"
fmt.Println(p)
go run concatenate.goStoryBook
1.6.3. Using the Join method
q := []string{"meetgor.com", "tags", "golang", "string"}
r := strings.Join(q, "/")
fmt.Println(r)
go run concatenate.gomeetgor.com/tags/golang/string
1.6.4. Using Sprintf method
// Using Sprintf function to format stringsname := "peter"
domain := "telecom"
service := "ceo"email := fmt.Sprintf("%s.%s@%s.com", service, name, domain)
fmt.Println(email)
go run concatenate.goceo.peter@telecom.com
1.6.5. Using Go string Builder method
package mainimport ("fmt""strings"
)func main() {// Using Builder functionc := []string{"j", "a", "v", "a"}var builder strings.Builderfor _, item := range c {builder.WriteString(item)}fmt.Println("builder = ", builder.String())b := []byte{'s', 'c', 'r', 'i', 'p', 't'}for _, item := range b {builder.WriteByte(item)}fmt.Println("builder = ", builder.String())builder.WriteRune('s')fmt.Println("builder = ", builder.String())fmt.Println("builder = ", builder)
}
go run concatenate.gobuilder = java
builder = javascript
builder = javascripts
builder = {0xc000088dd8 [106 97 118 97 115 99 114 105 112 116 115]}
1.6.6. Using the Bytes buffer method
package mainimport ("fmt""bytes"
)func main() {// Using bytes buffer methodvar buf bytes.Bufferfor i := 0; i < 2; i++ {buf.WriteString("ja")}fmt.Println(buf.String())buf.WriteByte('r')fmt.Println(buf.String())k := []rune{'s', 'c', 'r', 'i', 'p', 't'}for _, item := range k {buf.WriteRune(item)}fmt.Println(buf.String())
}
go run concatenate.gojaja
jajar
jajarscript
{[106 97 106 97 114 115 99 114 105 112 116] 0 0}
1.7. String Comparison
1.7.1. Using Comparison operators
package mainimport "fmt"func main() {s1 := "gopher"s2 := "Gopher"s3 := "gopher"isEqual := s1 == s2//"gopher" is not same as "Gopher" and hence `false`fmt.Printf("S1 and S2 are Equal? %t \n", isEqual)fmt.Println(s1 == s2)// "gopher" is not equal to "Gopher" and hence `true`fmt.Println(s1 != s2)// "Gopher" comes first lexicographically than "gopher" so return true // G -> 71 in ASCII and g -> 103fmt.Println(s2 < s3)fmt.Println(s2 <= s3)// "Gopher" is not greater than "gopher" as `G` comes first in ASCII table// So G value is less than g i.e. 71 > 103 which is falsefmt.Println(s2 > s3)fmt.Println(s2 >= s3)}
go run comparison.goS1 and S2 are Equal? false
false
true
true
true
false
false
1.7.2. Using Compare method
package mainimport("fmt""strings"
)func main() {s1 := "gopher"s2 := "Gopher"s3 := "gopher"fmt.Println(strings.Compare(s1, s2))fmt.Println(strings.Compare(s1, s3))fmt.Println(strings.Compare(s2, s3))
}
go run comparison.go1
0
-1
1.7.3. Using strings EqualFold
package mainimport("fmt""strings"
)func main() {s1 := "gopher"s2 := "Gopher"s3 := "gophy"fmt.Println(strings.EqualFold(s1, s2))fmt.Println(strings.EqualFold(s1, s3))fmt.Println(strings.EqualFold(s2, s3))
}
go run comparison.gotrue
false
false
1.8. String Manipulation and utility methods
1.8.1. ToLower, ToUpper and Title functions
package mainimport ("fmt""strings""golang.org/x/text/cases""golang.org/x/text/language"
)func main() {s1 := "Ubuntu 22"s2 := "meet"s3 := "IND"fmt.Println(strings.ToLower(s1))fmt.Println(strings.ToLower(s2))fmt.Println(strings.ToLower(s3))fmt.Printf("\n")fmt.Println(strings.ToUpper(s1))fmt.Println(strings.ToUpper(s2))fmt.Println(strings.ToUpper(s3))fmt.Printf("\n")cases := cases.Title(language.English)fmt.Println(cases.String(s1))fmt.Println(cases.String(s2))fmt.Println(cases.String(s3))
}
# 100-days-of-golang/scripts/stringsgo mod init
go get golang.org/x/text/cases
go get golang.org/x/text/languagego run utility.go
ubuntu 22
meet
indUBUNTU 22
MEET
INDUbuntu 22
Meet
Ind
1.8.2. Contains and ContainsAny functions
package mainimport ("fmt""strings"
)func main() {str := "javascript"substr := "script"s := "python"fmt.Println(strings.Contains(str, substr))fmt.Println(strings.Contains(str, s))fmt.Println(strings.ContainsAny(str, "joke"))fmt.Println(strings.ContainsAny(str, "xyz"))fmt.Println(strings.ContainsAny(str, ""))
}
$ go run main.gotrue
false
true
false
false
1.8.3. Split and SplitAfter functions
package mainimport ("fmt""strings"
)func main() {// Split method for splitting string into slice of stringlink := "meetgor.com/blog/golang/strings"fmt.Println(strings.Split(link, "/"))fmt.Println(strings.SplitAfter(link, "/"))// SplitAfter method for splitting string into slice of string with the patterndata := "200kms50kms120kms"fmt.Println(strings.Split(data, "kms"))fmt.Println(strings.SplitAfter(data, "kms"))
}
go run utility.go[meetgor.com blog golang strings]
[meetgor.com/ blog/ golang/ strings]
[200 50 120 ]
[200kms 50kms 120kms ]
1.8.4. Repeat and Fields functions
package mainimport ("fmt""strings"
)func main() {// Repeat method for creating strings with given string and integerpattern := "OK"fmt.Println(strings.Repeat(pattern, 3))
}
go run utility.goOKOKOK
package mainimport ("fmt""strings"
)func main() {// Fields method for extracting string from the given string with white space as delimiterstext := "Python is a prgramming language. Go is not"text_data := strings.Fields(text)fmt.Println(text_data)for _, d := range text_data {fmt.Println("data = ", d)}
}
go run utility.go[Python is a prgramming language. Go is not]
data = Python
data = is
data = a
data = prgramming
data = language.
data = Go
data = is
data = not
相关文章:
Golang 字符串
目录 1. Golang 字符串1.1. 基础概念1.2. 字符串编码1.3. 遍历字符串1.4. 类型转换1.5. 总结1.6. String Concatenation (字符串连接)1.6.1. Using the operator1.6.2. Using the operator1.6.3. Using the Join method1.6.4. Using Sprintf method1.6.5. Using Go string Bu…...
python应用中使用了multiprocessing多进程,使用pyinstaller打包出来的程序可能产生多个窗口
问题现象 我用pyside(类似pyqt)开发了一个应用程序。直接使用pycharm运行,一切都正常。但当我使用pyinstaller将它打包之后,再去运运行,发现窗口总是产生多个。 问题分析 直接运行没有问题,那么问题肯定…...
数据结构与算法——13.队列的拓展
这篇文章主要讲一下双端队列,优先队列,阻塞队列等队列的拓展内容。 目录 1.队列拓展概述 2.双端队列的链表实现 3.双端队列的数组实现 4.优先队列无序数组实现 5.阻塞队列 6.总结 1.队列拓展概述 首先来看一张图,来大致了解一下他们的…...
机器学习入门教学——损失函数(交叉熵法)
1、前言 我们在训练神经网络时,最常用到的方法就是梯度下降法。在了解梯度下降法前,我们需要了解什么是损失(代价)函数。所谓求的梯度,就是损失函数的梯度。如果不知道什么是梯度下降的,可以看一下这篇文章:机器学习入…...
pytest一些常见的插件
Pytest拥有丰富的插件架构,超过800个以上的外部插件和活跃的社区,在PyPI项目中以“ pytest- *”为标识。 本篇将列举github标星超过两百的一些插件进行实战演示。 插件库地址:http://plugincompat.herokuapp.com/ 1、pytest-html࿱…...
基于51单片机多路DTH11温湿度检测控制系统
一、系统方案 1、本设计采用51单片机作为主控器。 2、DHT11采集温度度,支持3路温度度,液晶1602显示。 3、按键设置报警阀值。 4、系统声光报警。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 //初始化LCD*********…...
宝塔重装注意事项
欢迎关注我的公众号:夜说猫,让一个贫穷的程序员不靠打代码也能吃饭~ 前言 宝塔8.0版本,宝塔卸载重装,或者重装Linux系统后重新安装宝塔也适用。 不能上来直接就执行安装宝塔脚本,除非之前没有安装过宝塔。 步骤 1、…...
【MySQL】 MySQL的增删改查(进阶)--壹
文章目录 🛫数据库约束🌴约束类型🎋NOT NULL约束🎍UNIQUE:唯一约束🌳DEFAULT:默认值约束🎄PRIMARY KEY:主键约束🍀FOREIGN KEY:外键约束…...
Map<K,V>的使用和List学习
Map Map是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。对于静态类型的查找来说,一般直接遍历或者用二分查找【不会对区间进行插入和删除操作】 而在现实生活中的查找比如: 根据姓名查询考试成绩通讯录…...
Flask实现Web服务调用Python程序
Flask实现Web服务调用Python程序_flask调用python程序_小白白程序员的博客-CSDN博客 【小沐学Python】Python实现Web服务器(Flask入门)_python flask web开发_爱看书的小沐的博客-CSDN博客...
步步为营,如何将GOlang引用库的安全漏洞修干净
文章目录 引场景构建第一步、直接引用的第三方库升级修复策略1.确认是否为直接引用的第三方库2.找到需要升级的版本是否为release版本 第二步、间接引用的第三方库升级修复策略那么问题来了,我们这么间接引用库的对应的直接引用库是哪个呢? (…...
as-if-serial与happens-before原则详解
文章目录 前言详解解决多线程下的问题 Happens-before原则总结as-if-serial语义happens-before的例子 前言 "as-if-serial"原则是Java内存模型中的一个重要概念。该规则规定:不管怎么重排序(编译期间的重排序,指令级并行的重排序&…...
基于Yolov8的工业小目标缺陷检测(2):动态蛇形卷积(Dynamic Snake Convolution),实现暴力涨点 | ICCV2023
目录 1.工业油污数据集介绍 1.1 小目标定义 1.2 难点 1.3 工业缺陷检测算法介绍 1.3.1 YOLOv8...
ARM64汇编基础
ARM64汇编基础 主要内容 到目前为止,大部分的移动设备都是64位的arm架构,一直想抽个时间系统学习下,这个周末就专门来学习下。毕竟两天的时间,也只是简单的入门了解下,为后续工作和学习打下基础。 本次学习的主要内容…...
Nodejs 第十六章(ffmpeg)
FFmpeg 是一个开源的跨平台多媒体处理工具,可以用于处理音频、视频和多媒体流。它提供了一组强大的命令行工具和库,可以进行视频转码、视频剪辑、音频提取、音视频合并、流媒体传输等操作。 FFmpeg 的主要功能和特性: 格式转换:…...
k8s集群部署es
集群内创建需要用到存储,此处举例使用腾讯云cfs共享存储 内存limits限制不需要加,否则会经常内存溢出导致es集群故障 apiVersion: apps/v1 kind: StatefulSet metadata:name: es7-clusternamespace: elasticsearch spec:serviceName: es-clusterreplica…...
学习记忆——宫殿篇——记忆宫殿——记忆桩——火车+外院+客厅+卧室
护板 警示灯 烟筒 采集箱 司炉室 桥 电线杆 棚顶 车厢 护栏 植物 石阶 水泥台 竹门 树干 躺椅 柱子 墙 池 洞 方灯 枕头 树 浴池 墙 射灯 藤条 浴巾框 耳环 窗户 灯 沙发 壁炉 吊灯 兵马俑 门 石佛 沙发椅 圆木 弧形木箱盖 床 窗帘 画板 纸伞 花 沙发背 颜料 抽屉...
QT用户登录注册,数据库实现
登录窗口头文件 #ifndef LOGINUI_H #define LOGINUI_H#include <QWidget> #include <QLineEdit> #include <QPushButton> #include <QLabel> #include <QMessageBox>#include <QSqlDatabase> //数据库管理类 #include <QSqlQuery> …...
GEE学习总结(9)——像元二分法计算月度植被覆盖度(MODIS)
像元二分法计算植被覆盖度 通过MODIS的NDVI数据集MOD13Q1和像元二分法计算植被覆盖度 var multi_NDVI ee.ImageCollection(MODIS/006/MOD13Q1).filterDate(2015-06-01, 2016-09-01).select(NDVI).max().divide(10000).clip(geometry);var ndviVis {min: 0.0,max: 1,palette…...
RabbitMQ用户命令_策略_日志
RabbitMQ相关安装 Centos离线安装RabbitMQ并开启MQTT Docker安装rabbitMQ RabbitMQ集群搭建和测试总结_亲测 Docker安装RabbitMQ集群_亲测成功 RabbitMQ创建管理员命令 #查看当前用户命令: rabbitmqctl list_users#创建用户和密码 rabbitmqctl add_user admin…...
2025届必备的十大AI写作神器实际效果
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 在当下的学术写作情形里,论文AI网站借助自然语言处理跟深度学习技术,…...
给App开发者的冷知识:你的应用想进系统分区?聊聊/system/priv-app/、/system/app/和/system_ext/app/的门槛
Android系统分区应用部署指南:从/system/priv-app/到/system_ext/app/的深度解析 在Android生态系统中,系统分区应用的部署策略一直是开发者们关注的焦点。不同于普通应用商店分发的APK,能够进入系统分区的应用往往意味着更高的权限、更深的系…...
告别激活烦恼:3分钟掌握KMS_VL_ALL_AIO智能激活工具
告别激活烦恼:3分钟掌握KMS_VL_ALL_AIO智能激活工具 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统激活而烦恼吗?Office软件突然变成只读模式影响工作…...
Windows 11系统优化深度解析:自动化精简工具的技术实现与架构设计
Windows 11系统优化深度解析:自动化精简工具的技术实现与架构设计 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder Windows 11系统优化一直是技术社区关…...
轻量级工作流引擎pacexy/flow:用代码解耦复杂业务逻辑
1. 项目概述:一个面向开发者的现代化工作流引擎最近在和一些做中后台应用、自动化工具的朋友交流时,大家普遍提到一个痛点:随着业务逻辑越来越复杂,代码里到处是if-else和状态判断,一个核心流程动辄几百行,…...
重塑你的数字工作空间:Farouk‘s Homepage主题深度体验指南
重塑你的数字工作空间:Farouks Homepage主题深度体验指南 【免费下载链接】obsidian-homepage Obsidian homepage - Minimal and aesthetic template (with my unique features) 项目地址: https://gitcode.com/gh_mirrors/obs/obsidian-homepage 还在为Obsi…...
你的手机也能接收太空图片:SSTV解码应用Robot36全解析
你的手机也能接收太空图片:SSTV解码应用Robot36全解析 【免费下载链接】robot36 Decode SSTV encoded audio signals to images 项目地址: https://gitcode.com/gh_mirrors/ro/robot36 想象一下,你正在山区徒步旅行,手机突然收到一段奇…...
Hide Mock Location:彻底隐藏Android模拟位置设置的终极解决方案
Hide Mock Location:彻底隐藏Android模拟位置设置的终极解决方案 【免费下载链接】HideMockLocation Xposed module to hide the mock location setting. 项目地址: https://gitcode.com/gh_mirrors/hi/HideMockLocation 你是否曾经因为开启"允许模拟位…...
将 Claude Code 编程助手对接至 Taotoken 的 Anthropic 兼容通道
将 Claude Code 编程助手对接至 Taotoken 的 Anthropic 兼容通道 1. 准备工作 在开始配置之前,请确保您已经完成以下准备工作:拥有有效的 Taotoken 账户并获取了 API Key,同时在本地或开发环境中安装了 Claude Code 编程助手。Taotoken 平台…...
Python调用国密SM2/SM3不再踩坑:5个被90%项目忽略的合规性校验与性能优化关键点
更多请点击: https://intelliparadigm.com 第一章:Python国密SM2/SM3工程化落地的现状与挑战 当前,Python生态中支持国密算法(SM2椭圆曲线公钥加密、SM3哈希)的成熟库仍处于演进阶段。主流方案依赖gmssl(C…...
