当前位置: 首页 > news >正文

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
}

前面已经讲解 stringrunebyte 的区别和联系,这里再理解他们的转换,是不是就轻松很多了呢。

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&#xff08;类似pyqt&#xff09;开发了一个应用程序。直接使用pycharm运行&#xff0c;一切都正常。但当我使用pyinstaller将它打包之后&#xff0c;再去运运行&#xff0c;发现窗口总是产生多个。 问题分析 直接运行没有问题&#xff0c;那么问题肯定…...

数据结构与算法——13.队列的拓展

这篇文章主要讲一下双端队列&#xff0c;优先队列&#xff0c;阻塞队列等队列的拓展内容。 目录 1.队列拓展概述 2.双端队列的链表实现 3.双端队列的数组实现 4.优先队列无序数组实现 5.阻塞队列 6.总结 1.队列拓展概述 首先来看一张图&#xff0c;来大致了解一下他们的…...

机器学习入门教学——损失函数(交叉熵法)

1、前言 我们在训练神经网络时&#xff0c;最常用到的方法就是梯度下降法。在了解梯度下降法前&#xff0c;我们需要了解什么是损失(代价)函数。所谓求的梯度&#xff0c;就是损失函数的梯度。如果不知道什么是梯度下降的&#xff0c;可以看一下这篇文章&#xff1a;机器学习入…...

pytest一些常见的插件

Pytest拥有丰富的插件架构&#xff0c;超过800个以上的外部插件和活跃的社区&#xff0c;在PyPI项目中以“ pytest- *”为标识。 本篇将列举github标星超过两百的一些插件进行实战演示。 插件库地址&#xff1a;http://plugincompat.herokuapp.com/ 1、pytest-html&#xff1…...

基于51单片机多路DTH11温湿度检测控制系统

一、系统方案 1、本设计采用51单片机作为主控器。 2、DHT11采集温度度&#xff0c;支持3路温度度&#xff0c;液晶1602显示。 3、按键设置报警阀值。 4、系统声光报警。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 //初始化LCD*********…...

宝塔重装注意事项

欢迎关注我的公众号&#xff1a;夜说猫&#xff0c;让一个贫穷的程序员不靠打代码也能吃饭~ 前言 宝塔8.0版本&#xff0c;宝塔卸载重装&#xff0c;或者重装Linux系统后重新安装宝塔也适用。 不能上来直接就执行安装宝塔脚本&#xff0c;除非之前没有安装过宝塔。 步骤 1、…...

【MySQL】 MySQL的增删改查(进阶)--壹

文章目录 &#x1f6eb;数据库约束&#x1f334;约束类型&#x1f38b;NOT NULL约束&#x1f38d;UNIQUE&#xff1a;唯一约束&#x1f333;DEFAULT&#xff1a;默认值约束&#x1f384;PRIMARY KEY&#xff1a;主键约束&#x1f340;FOREIGN KEY&#xff1a;外键约束&#x1f…...

Map<K,V>的使用和List学习

Map Map是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例化子类有关。对于静态类型的查找来说&#xff0c;一般直接遍历或者用二分查找【不会对区间进行插入和删除操作】 而在现实生活中的查找比如&#xff1a; 根据姓名查询考试成绩通讯录…...

Flask实现Web服务调用Python程序

Flask实现Web服务调用Python程序_flask调用python程序_小白白程序员的博客-CSDN博客 【小沐学Python】Python实现Web服务器&#xff08;Flask入门&#xff09;_python flask web开发_爱看书的小沐的博客-CSDN博客...

步步为营,如何将GOlang引用库的安全漏洞修干净

文章目录 引场景构建第一步、直接引用的第三方库升级修复策略1.确认是否为直接引用的第三方库2.找到需要升级的版本是否为release版本 第二步、间接引用的第三方库升级修复策略那么问题来了&#xff0c;我们这么间接引用库的对应的直接引用库是哪个呢&#xff1f; &#xff08;…...

as-if-serial与happens-before原则详解

文章目录 前言详解解决多线程下的问题 Happens-before原则总结as-if-serial语义happens-before的例子 前言 "as-if-serial"原则是Java内存模型中的一个重要概念。该规则规定&#xff1a;不管怎么重排序&#xff08;编译期间的重排序&#xff0c;指令级并行的重排序&…...

基于Yolov8的工业小目标缺陷检测(2):动态蛇形卷积(Dynamic Snake Convolution),实现暴力涨点 | ICCV2023

目录 1.工业油污数据集介绍 1.1 小目标定义 1.2 难点 1.3 工业缺陷检测算法介绍 1.3.1 YOLOv8...

ARM64汇编基础

ARM64汇编基础 主要内容 到目前为止&#xff0c;大部分的移动设备都是64位的arm架构&#xff0c;一直想抽个时间系统学习下&#xff0c;这个周末就专门来学习下。毕竟两天的时间&#xff0c;也只是简单的入门了解下&#xff0c;为后续工作和学习打下基础。 本次学习的主要内容…...

Nodejs 第十六章(ffmpeg)

FFmpeg 是一个开源的跨平台多媒体处理工具&#xff0c;可以用于处理音频、视频和多媒体流。它提供了一组强大的命令行工具和库&#xff0c;可以进行视频转码、视频剪辑、音频提取、音视频合并、流媒体传输等操作。 FFmpeg 的主要功能和特性&#xff1a; 格式转换&#xff1a;…...

k8s集群部署es

集群内创建需要用到存储&#xff0c;此处举例使用腾讯云cfs共享存储 内存limits限制不需要加&#xff0c;否则会经常内存溢出导致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创建管理员命令 #查看当前用户命令&#xff1a; rabbitmqctl list_users#创建用户和密码 rabbitmqctl add_user admin…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...