Go语言核心手册-1.字符串

简介: ASCII是英文“American Standard Code for Information Interchange”的缩写,中文译为美国信息交换标准代码,它是由美国国家标准学会(ANSI)制定的单字节字符编码方案,它使用单个字节(byte)的二进制数来编码一个字符。

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编码值,前者是(便于我们人类理解的)外部展现,后者是(便于计算机系统理解的)内在表达,请看下面代码:

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编码值都拆成相应的字节序列。

image.png

一句话总结一下:一个string类型的值在底层就是一个能够表达若干个UTF-8编码值的字节序列。


1.3 遍历字符串


range遍历:

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: '爱' [e7 88 b1]5: '好' [e5 a5 bd]8: '者' [e8 80 85]for 遍历:0: [G] [47]1: [o] [6f]2: [ç] [e7]3: [ˆ] [88]4: [±] [b1]5: [å] [e5]6: [¥] [a5]7: [½] [bd]8: [è] [e8]9: [€] [80]10: […] [85]

由此可以看出,通过range方式的遍历,是以rune为单位,但是相邻字符的索引值并不一定是连续的;通过for方式的遍历,是以byte为单位。


1.4 类型转换


字符串是不能直接修改的,如果需要修改,需要转换为可变类型([]rune和[]bype),待修改完后再转换回来。但不管如何转换,都需要重新分配内存,并复制数据.

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

相关文章
|
22小时前
|
存储 编译器 Go
|
3天前
|
安全 Java Go
探索Go语言在高并发环境中的优势
在当今的技术环境中,高并发处理能力成为评估编程语言性能的关键因素之一。Go语言(Golang),作为Google开发的一种编程语言,以其独特的并发处理模型和高效的性能赢得了广泛关注。本文将深入探讨Go语言在高并发环境中的优势,尤其是其goroutine和channel机制如何简化并发编程,提升系统的响应速度和稳定性。通过具体的案例分析和性能对比,本文揭示了Go语言在实际应用中的高效性,并为开发者在选择合适技术栈时提供参考。
|
23小时前
|
算法 安全 Go
|
2天前
|
监控 NoSQL Go
Go语言中高效使用Redis的Pipeline
Redis 是构建高性能应用时常用的内存数据库,通过其 Pipeline 和 Watch 机制可批量执行命令并确保数据安全性。Pipeline 类似于超市购物一次性结账,减少网络交互时间,提升效率。Go 语言示例展示了如何使用 Pipeline 和 Pipelined 方法简化代码,并通过 TxPipeline 保证操作原子性。Watch 机制则通过监控键变化实现乐观锁,防止并发问题导致的数据不一致。这些机制简化了开发流程,提高了应用程序的性能和可靠性。
7 0
|
4天前
|
NoSQL Go Redis
Go语言中如何扫描Redis中大量的key
在Redis中,遍历大量键时直接使用`KEYS`命令会导致性能瓶颈,因为它会一次性返回所有匹配的键,可能阻塞Redis并影响服务稳定性。为解决此问题,Redis提供了`SCAN`命令来分批迭代键,避免一次性加载过多数据。本文通过两个Go语言示例演示如何使用`SCAN`命令:第一个示例展示了基本的手动迭代方式;第二个示例则利用`Iterator`简化迭代过程。这两种方法均有效地避免了`KEYS`命令的性能问题,并提高了遍历Redis键的效率。
17 0
|
Go 索引
golang 字符串操作实例
package main import s "strings" import "fmt" var p = fmt.Println func main() { p("Contains: ", s.
895 0
|
10天前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
6天前
|
运维 Kubernetes Go
"解锁K8s二开新姿势!client-go:你不可不知的Go语言神器,让Kubernetes集群管理如虎添翼,秒变运维大神!"
【8月更文挑战第14天】随着云原生技术的发展,Kubernetes (K8s) 成为容器编排的首选。client-go作为K8s的官方Go语言客户端库,通过封装RESTful API,使开发者能便捷地管理集群资源,如Pods和服务。本文介绍client-go基本概念、使用方法及自定义操作。涵盖ClientSet、DynamicClient等客户端实现,以及lister、informer等组件,通过示例展示如何列出集群中的所有Pods。client-go的强大功能助力高效开发和运维。
29 1
|
7天前
|
SQL 关系型数据库 MySQL
Go语言中使用 sqlx 来操作 MySQL
Go语言因其高效的性能和简洁的语法而受到开发者们的欢迎。在开发过程中,数据库操作不可或缺。虽然Go的标准库提供了`database/sql`包支持数据库操作,但使用起来稍显复杂。为此,`sqlx`应运而生,作为`database/sql`的扩展库,它简化了许多常见的数据库任务。本文介绍如何使用`sqlx`包操作MySQL数据库,包括安装所需的包、连接数据库、创建表、插入/查询/更新/删除数据等操作,并展示了如何利用命名参数来进一步简化代码。通过`sqlx`,开发者可以更加高效且简洁地完成数据库交互任务。
16 1