文章目录

  • 07 Go语言字符串
    • 7.1 字符串类型
    • 7.2 Unicode & UTF-8
      • Unicode
      • UTF-8
    • 7.3 字符串字面量
    • 7.4 字符串基本操作
      • 返回字节数:使用函数len()
      • 索引操作:使用[n]
      • 截取子串:使用[m:n]
      • 连接字符串:使用 + 号
      • 字符串比较
      • 遍历字符串
      • 字符串转[]byte
      • 字符串转[]rune
    • 7.5 strings包简介
      • strings.Contains
      • strings.ContainsAny
      • strings.ContainsRune
      • strings.Index
      • strings.LastIndex
      • strings.IndexRune
      • strings.IndexAny
      • strings.LastIndexAny
      • strings.HasPrefix
      • strings.HasSuffix
      • strings.ToUpper、strings.ToLower
      • strings.TrimSpace
      • strings.EqualFold

07 Go语言字符串

7.1 字符串类型

在Go语言中,字符串属于基本类型,因此字符串也是值类型。

字符串的值不可变,创建某个字符串后无法修改这个字符串的内容,更深入地讲,字符串是字节的定长数组。

实际上,字符串的底层实现是一个定长的字节序列。该字节序列中可以包含任意数值,包括0值字节。

s1 := "Hello World"var s2 string = "Hello World"var s3 string
s3 = "Hello World"

7.2 Unicode & UTF-8

Unicode

早期,美国发明计算机的时候,只需要存储英文字符。那时,只需要使用7个比特位就可以表示所有的英文字符了(7个比特位可以表示128个字符)。当时发明了一个编码:ASCII码(美国信息交换标准码)。ASCII码使用7位标识128个字符,其中有:大小写英文字母、数字、标点符号和一些设备控制符。但随着信息计数的发展,世界上许多使用其他语言的人没有办法在计算机上使用自己的文字字符,于是,后来又搞出了Unicode码。

Unicode为目前世界上所有的文字系统中的符号都进行了编码,为每个字符赋予了一个叫Unicode码点的数值。为了保持对ASCII码的兼容,0到127之间的码点对应的字符与ASCII码完全一致。

Unicode包含的字符简直太多了,要表示所有的字符,需要用到32个位(4个字节)。在Go中,这样一个Unicode码点被称作rune。Go还专门提供了一个类型rune,用来存放Unicode码点。实际上,在Go中类型rune是int32的别名。

我们可以使用int32序列来表示字符串,这样,在该字符串中可以出现世界上所有的文字。这种编码方式有个专门的名字,叫UTF-32,即,每个Unicode码点都用4字节来存放。由于UTF-32是定长编码(每个码点用相同长度来存放),因此这种编码方式很便于程序处理。但UTF-32方式的缺点是:即使存放码点的值为0到127之间的字符,也要用4个字节。这太浪费了。因此,又搞出来一个UTF-8。

UTF-8

UTF-8以字节为单位对Unicode码点做变长编码。

每个文字符号使用1~4个字节来表示。首字节高位指明了后面还有多少字节。

  • 如果最高位为0,则表示仅占1字节,该字节的低7位是ASCII码,这与早期出现的ASCII保持一致。
  • 如果最高位为110,则表示占2字节,并规定第二个字节需要以10开始。
  • 如果最高位为1110,则表示占3字节,并规定后续字节需要以10开始。
  • 如果最高位位11110,则表示占4字节,并规定后续字节需要以10开始。

见下面所示:

0xxxxxxx                                 码点0~127             ASCII
110xxxxx 10xxxxxx                           码点128~2047
1110xxxx 10xxxxxx 10xxxxxx                  码点2048~65535
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx         码点65536~0x10ffff

由于绝大部分的文本中出现的字符的Unicode码点都小于65536,甚至对于纯英文文本中的字符来说,Unicode码点小于128。因此使用UTF-8与UTF-32比起来更加节省空间。而且,要在UTF-8编码中定位一个字符的起始位置时,最多向前追溯3个字节即可找到。

Go语言的源文件需要以UTF-8编码存放,而且Go语言字符串的底层字节序列中也是以UTF-8编码存放数据。

示例:

s := "Hello World"
fmt.Println(s)// 按字节比较
r1 := s == "Hello World"
r2 := s > "Hi"// 改变字符串内容 - 编译错误: 字符串不可改变
// s[0] = 'A'

7.3 字符串字面量

字符串字面量:直接以字符串值得形式出现在代码中。也就是带双引号的字符序列,例如:

"Hello, World!"

有些特殊字符无法用键盘输入,那么如何在字符串字面量中表示呢。Go语言提供了字符转义的功能。

在字符串字面量中,使用反斜杠(\)后跟特定字符来指明一些特殊ASCII字符。比如:

\a       响铃符
\b      退格符
\f      换页符
\n      换行符
\r      回车符
\t      制表符
\v      垂直制表符
\'     单引号
\"     双引号
\\      反斜杠

也可以用(\x)或(\o)来后跟16进制或8进制数来表示单个字节。注意,是单个字节。常用于在字符串中安放任意的字节序列,比如:

"\x2c\x30\x45\x66"
"\o123\o46\o55"

也可以使用(\u)或(\U)后跟16位或32位Unicode码点值来表示任意的Unicode字符。注意,实际占几个字节取决与该Unicode码点的UTF-8编码占多少字节。比如:

"\u4e16\u754c"
"\U00004e16\U0000754c"

原生的字符串字面量,以两个反引号(`)包含的字符序列称作原生字符串,它里面的任何内容都不会被转义,而是原模原样存放在字符串中。原生字符串适合于HTML模板、JSON字面量、文本提示信息等等:

`<html>
<body>
Hello World
</body>
</html>``{"greeting": "Hello""to": "World"
}`

7.4 字符串基本操作

返回字节数:使用函数len()

s := "Hello World"// 返回字符串的字节数  -- 记住是字节数,不是字符数,一个UTF8编码的字符可能用1~4个字节表示
cnt := len(s)
fmt.Println(cnt)

索引操作:使用[n]

s := "Hello World"// 返回第n个字节的值  -- 返回的是第n个字节,不是字符
fmt.Println(s[0], s[1])// 不可越界访问,越界访问会触发宕机异常
// c := s[len(s)]

截取子串:使用[m:n]

s := "Hello World"//截取子串  -- 返回的字串是一个新字符串
s1 := s[2:5]       // 从下标2到5,含2不含5
s2 := s[2:]        // 从下标2到最后
s3 := s[:5]        // 从开始到下标5,不含5// 截取字串不能越界,越界会触发宕机异常
// s4 := s[2:30]

连接字符串:使用 + 号

s1 := "Hello "
s2 := "World"// +号连接两个字符串生成一个新字符串
s := s1 + s2

字符串比较

s1 := "Hello World"
s2 := "hello world"fmt.Println(s1 == s2)   // false
fmt.Println(s1 != s2)  // true
fmt.Println(s1 < s2) // true
fmt.Println(s1 > s2) // false
fmt.Println(s1 <= s2)   // true
fmt.Println(s1 >= s2)   // false

遍历字符串

方式1,使用下标遍历(按字节遍历字符串):

s := "Hello 世界"for i := 0; i < len(s); i++ {fmt.Printf("%c", s[i])
}// 输出
// Hello 世界

方式2,使用for-range遍历(按字符遍历字符串):

s := "Hello 世界"for _, v := range s {fmt.Printf("%c", v)
}// 输出
// Hello 世界

字符串转[]byte

在Golang中,不能修改字符串的内容,如果要对字符串中的字节进行修改,需要先转换为[]byte类型。

[]byte类型是字节切片类型,后面的课程将详细介绍。

s := "Hello 世界"
b := []byte(s) // 转为[]byte类型,会自动复制数据到[]byte中(暂时可以这样理解)
b[5] = ','
fmt.Printf("%s\n", s)
fmt.Printf("%s\n", b)// 输出
// Hello 世界
// Hello,世界

字符串转[]rune

[]rune类型是rune切片类型。前面已经介绍过了rune用于存放Unicode码点。

s := "Hello 世界"
b := []rune(s)    // 转换为[]rune类型,数据被自动复制到[]rune中。
b[6] = '中'
b[7] = '国'
fmt.Println(s)
fmt.Println(string(b))// 输出
// Hello 世界
// Hello 中国

7.5 strings包简介

Go语言的标准库中的strings包,专门提供了用于处理字符串的函数。

strings.Contains

// 判断s中是否包含子串substr
func Contains(s, substr string) bool

示例:

s := "Hello,世界!!!!!"
b := strings.Contains(s, "!!")
fmt.Println(b) // true
b = strings.Contains(s, "!?")
fmt.Println(b) // false
b = strings.Contains(s, "")
fmt.Println(b) // true

strings.ContainsAny

// 判断s中是否包含 chars 中的任何一个字符
func ContainsAny(s, chars string) bool

示例:

s := "Hello,世界!"
b := strings.ContainsAny(s, "abc")
fmt.Println(b) // false
b = strings.ContainsAny(s, "def")
fmt.Println(b) // true
b = strings.Contains(s, "")
fmt.Println(b) // true

strings.ContainsRune

// 判断s中是否包含字符 r
func ContainsRune(s string, r rune) bool

示例:

s := "Hello,世界!"
b := strings.ContainsRune(s, '\n')
fmt.Println(b) // false
b = strings.ContainsRune(s, '界')
fmt.Println(b) // true
b = strings.ContainsRune(s, 0)
fmt.Println(b) // false

strings.Index

// 返回子串 sep 在字符串 s 中第一次出现的位置
// 如果找不到,则返回 -1,如果 sep 为空,则返回 0。
func Index(s, sep string) int

示例:

s := "Hello,世界!"
i := strings.Index(s, "h")
fmt.Println(i) // -1
i = strings.Index(s, "!")
fmt.Println(i) // 12
i = strings.Index(s, "")
fmt.Println(i) // 0

strings.LastIndex

// 返回子串 sep 在字符串 s 中最后一次出现的位置
// 如果找不到,则返回 -1,如果 sep 为空,则返回字符串的长度
func LastIndex(s, sep string) int

示例:

s := "Hello,世界! Hello!"
i := strings.LastIndex(s, "h")
fmt.Println(i) // -1
i = strings.LastIndex(s, "H")
fmt.Println(i) // 14
i = strings.LastIndex(s, "")
fmt.Println(i) // 20

strings.IndexRune

// 返回字符 r 在字符串 s 中第一次出现的位置
// 如果找不到,则返回 -1
func IndexRune(s string, r rune) int

示例:

s := "Hello,世界! Hello!"
i := strings.IndexRune(s, '\n')
fmt.Println(i) // -1
i = strings.IndexRune(s, '界')
fmt.Println(i) // 9
i = strings.IndexRune(s, 0)
fmt.Println(i) // -1

strings.IndexAny

// 返回字符串 chars 中的任何一个字符在字符串 s 中第一次出现的位置
// 如果找不到,则返回 -1,如果 chars 为空,则返回 -1
func IndexAny(s, chars string) int

示例:

s := "Hello,世界! Hello!"
i := strings.IndexAny(s, "abc")
fmt.Println(i) // -1
i = strings.IndexAny(s, "dof")
fmt.Println(i) // 1
i = strings.IndexAny(s, "")
fmt.Println(i) // -1

strings.LastIndexAny

// 返回字符串 chars 中的任何一个字符在字符串 s 中最后一次出现的位置
// 如果找不到,则返回 -1,如果 chars 为空,也返回 -1
func LastIndexAny(s, chars string) int

示例:

s := "Hello,世界! Hello!"
i := strings.LastIndexAny(s, "abc")
fmt.Println(i) // -1
i = strings.LastIndexAny(s, "def")
fmt.Println(i) // 15
i = strings.LastIndexAny(s, "")
fmt.Println(i) // -1

strings.HasPrefix

// 判断字符串 s 是否以 prefix 开头
func HasPrefix(s, prefix string) bool

示例:

s := "Hello 世界!"
b := strings.HasPrefix(s, "hello")
fmt.Println(b) // false
b = strings.HasPrefix(s, "Hello")
fmt.Println(b) // true

strings.HasSuffix

// 判断字符串 s 是否以 prefix 结尾
func HasSuffix(s, suffix string) bool

示例:

s := "Hello 世界!"
b := strings.HasSuffix(s, "世界")
fmt.Println(b) // false
b = strings.HasSuffix(s, "世界!")
fmt.Println(b)

strings.ToUpper、strings.ToLower

// 将 s 中的所有字符修改为其大写格式
func ToUpper(s string) string// 将 s 中的所有字符修改为其小写格式
func ToLower(s string) string

示例:

s := "heLLo worLd Abc"
us := strings.ToUpper(s)
ls := strings.ToLower(s)
fmt.Printf("%q\n", us) // "HELLO WORLD ABC"
fmt.Printf("%q\n", ls) // "hello world abc"

strings.TrimSpace

// 删除 s 首尾连续的的空白字符
func TrimSpace(s string) string

示例:

s := " Hello 世界! "
ts := strings.TrimSpace(s)
fmt.Printf("%q\n", ts) // "Hello 世界!"

strings.EqualFold

// EqualFold 判断 s 和 t 是否相等。忽略大小写,同时它还会对特殊字符进行转换
// 比如将“ϕ”转换为“Φ”、将“DŽ”转换为“Dž”等,然后再进行比较
func EqualFold(s, t string) bool

示例:

s1 := "Hello 世界! ϕ DŽ"
s2 := "hello 世界! Φ Dž"
b := strings.EqualFold(s1, s2)
fmt.Printf("%v\n", b) // true

Copyright@2022 , 359152155@qq.com

[Go语言入门] 07 Go语言字符串相关推荐

  1. c语言编程培训ppt,C语言入门经典-C语言编程.ppt

    <C语言入门经典-C语言编程.ppt>由会员分享,可在线阅读,更多相关<C语言入门经典-C语言编程.ppt(27页珍藏版)>请在人人文库网上搜索. 1.第01章 C语言编程,C ...

  2. c语言入门经典doc,C语言入门经典C语言编程.ppt

    C语言入门经典C语言编程.ppt 第01章 C语言编程,C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序即一组指令,并让计算机依指令行事 ...

  3. 编程入门c语言ppt,C语言入门经典-C语言编程.ppt

    <C语言入门经典-C语言编程.ppt>由会员分享,可在线阅读,更多相关<C语言入门经典-C语言编程.ppt(27页珍藏版)>请在装配图网上搜索. 1.第01章 C语言编程,C语 ...

  4. go语言视频教程_ go语言入门视频教程_go语言实战视频教程

    许多人可能知道go语言的优点在哪里,但他们不知道go语言适合在哪里使用.通过学习go语言视频教程,可以清楚的知道go语言主要用于服务器端开发,其定位是用来开发"大型软件".学习go ...

  5. C语言入门——初识C语言

    C语言入门--初识C语言 一. C语言的起源 二. 选择C语言的原因 (一). 设计特性 (二). 高效性 (三). 可移植性 (四). 强大而灵活 (五). 面向程序员 (六). 缺点 三. C语言 ...

  6. 入门C语言模板,C语言入门经典-C语言编程

    C语言入门经典-C语言编程Tag内容描述: 1.第01章C语言编程,C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让 ...

  7. 小学生c语言入门ppt,C语言入门至精完整版46759.ppt

    C语言入门至精完整版46759 第10章 指针 C语言程序设计 第十章 指针 地址和指针的概念 变量的指针和指向变量的指针变量 数组与指针 字符串与指针 指向函数的指针 返回指针值的函数 指针数组和指 ...

  8. c语言入门数组,C语言入门之数组(2)

    二维数组 前面介绍的数组只有一个下标,称为一维数组, 其数组元素也称为单下标变量.在实际问题中有很多量是二维的或多维的, 因此C语言允许构造多维数组.多维数组元素有多个下标, 以标识它在数组中的位置, ...

  9. 01《Go语言入门》Go语言简介:历史背景、发展现状及语言特性

    这是我纯手写的<Go语言入门>,手把手教你入门Go.源码+文章,看了你就会

最新文章

  1. Microsoft Visual C++ 14.0 is required错误解决办法
  2. php 实现 html转js
  3. 如何使用Git解决“错误:错误索引 - 致命:索引文件损坏”
  4. Java 数组长度和访问
  5. nik collection滤镜
  6. 五、开始学习Excel函数,效率快速提高
  7. 本科、硕士、博士,究竟有何区别?
  8. 在Elasticsearch中索引Java Bean的简单方法
  9. Codeforces Round #323 (Div. 2): C. GCD Table(思维题)
  10. mysql数据库:mysql增删改、单表、多表及子查询
  11. 六石编程学:自动化测试的优点
  12. Bing翻译接口(V3版本)
  13. 两种前端在线json编辑器方案(无法解决number精度丢失问题)
  14. 使用FileTypesMan修复office关联图标
  15. 机器学习之自然语言处理——中文分词jieba库详解(代码+原理)
  16. centos7 “v篇n“工具
  17. 山无棱-天地合-乃敢与君绝
  18. xiaoxin juju needs help
  19. 【Hyperledger Fabric入门】(一) 快速运行一个简单的Fabric网络2
  20. 互联网时代:天才与伟人的区别

热门文章

  1. GBase 8a MPP Cluster 认证培训资料汇总
  2. 椭圆型偏微分方程和格林函数
  3. PDF文档工具箱Stirling-PDF
  4. 自然语言处理(二十八):BERT介绍
  5. 六成大学生认为自己毕业10年内会年入百万!
  6. 学生信息表(本地存储)
  7. minio安装部署及使用
  8. 网上书店平台---设计活动
  9. NoteExpress使用中的一些问题
  10. matlab, 生成一个数值一样的n维列向量