这里填写标题

  • 1. Golang 字符串
    • 1.1. 基础概念
    • 1.2. 字符串编码
    • 1.3. 遍历字符串
    • 1.4. 类型转换
    • 1.5. 总结

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 语言中的相关数据类型以及日后的相关程序编写都会很有好处。

Golang 字符串相关推荐

  1. golang 字符串转整形 string 转 int ,go string 转 int

    golang 字符串转整形 string 转 int ,go string 转 int 初 代码: 效果 初 很多时候,我们会遇到需要使用 字符串 转 数字 的功能,我们可以用 strconv.Ato ...

  2. golang 字符串拼接 字符串数组转字符串

    1.字符串拼接 一般对于少量的字符串拼接可以直接用+来连接,不过最好的方法还是Builder. 用buffer.Builder,官方建议用这个. package mainimport ("f ...

  3. Golang字符串拼接的方法

    Golang字符串拼接的方法 three := []string{"a", "b1"}four := []string{"c01", &qu ...

  4. Golang字符串中常用的函数

    Golang字符串中常用的函数 说明: 字符串在我们程序开发中,使用的是非常多的,常用的函数需要同学们掌握: 下面列出20种常用的字符串函数: 1)统计字符串的长度,按字节len(str) 2)字符串 ...

  5. Golang字符串拼接

    Golang字符串拼接 Golang中字符串的拼接存在很多种方法,性能也存在明显的差异.考虑一种场景,需要连续地拼接大量字符串. 不同字符串拼接的性能对比 采用操作符+拼接 func Benchmar ...

  6. golang 字符串随机数_在Go中生成随机数和字符串

    golang 字符串随机数 While completely random is not really possible, we still can have pseudorandom numbers ...

  7. golang字符串拼接,字符串数组转字符串

    1.字符串拼接 一般对于少量的字符串拼接可以直接用+来连接,不过最好的方法还是Builder. 用buffer.Builder,官方建议用这个. package mainimport ("f ...

  8. golang 字符串排序_Golang操作数据库Redis

    在项目开发中redis的使用也比较频繁,本文介绍了Go语言中go-redis库的基本使用. Redis介绍 Redis是一个开源的内存数据库,Redis提供了多种不同类型的数据结构,很多业务场景下的问 ...

  9. golang 字符串分割

    1.func Fields(s string) []string,这个函数的作用是按照1:n个空格来分割字符串最后返回的是 []string的切片 import ("fmt"&qu ...

  10. golang 字符串拼接方式

    最近在做性能优化,有个函数里面的耗时特别长,看里面的操作大多是一些字符串拼接的操作,而字符串拼接在 golang 里面其实有很多种实现. 实现方法 1.直接使用运算符 func BenchmarkAd ...

最新文章

  1. Spark _12_每个网址的每个地区访问量 ,由大到小排序
  2. 我只是一只碌碌无为的工蚁 : (
  3. C#编程高并发的几种处理方法
  4. linux crypto cbc 接口,Linux 2.6.38.4: User-space interface for Crypto API
  5. 【BZOJ3609】人人尽说江南好,博弈
  6. c语言编写点餐系统的图形界面,「分享」C语言如何编写图形界面
  7. angular获取图片高宽_Angular 读书笔记
  8. CSS元素隐藏原理和效果小结
  9. Android 5.0 屏幕录制/截屏
  10. 《别做“正常”的傻瓜(全新第2版)》
  11. 软件文档的类型有哪些?
  12. openpyxl批量删除表格中的空白行,并处理数据样式
  13. StrandHogg漏洞修复
  14. 从头撸到脚,SpringBoot 就一篇全搞定!
  15. java后台地址(省,市,区)、姓名、手机号算法智能识别
  16. 创作者基金新上线互动类型 NFTs,快来为你的体验添砖加瓦吧~
  17. 【Rust日报】2022-02-09 热议帖 - 我TM的做开源没有得到任何资助
  18. 火影推荐程序连载14-Vue开源项目使用探索
  19. TMS320F28335调用官方库进行FFT频谱分析
  20. 固态移动硬盘“函数不正确”

热门文章

  1. 基于android的手机商城app
  2. 剧院在线选座票务系统
  3. 星际争霸2中文版下载 – 即时战略游戏超大作 (繁体含中文语音)
  4. 为什么使用LINUX(有点长,没耐心别看)大家自己体会
  5. java 某年某月的天数_1160-C语言实验——某年某月的天数-JAVA
  6. 瞎聊高速公路与主干道的立交匝道设计
  7. 在IE浏览器访问网址时显示证书错误,导航已阻止
  8. Note Of Effective C++ 、More Effective C++ And Effective Modern C++
  9. mysql左连接查询举例_mysql左右连接查询(有示例图)
  10. 第一章 ArcGIS初识