[TOC]
go语言的string是一种数据类型。这个数据类型占用16字节空间,前面8字节是一个指针,指向字符串的地址。后面八个字节是一个整数,标识字符串长度
## 字符串的存储原理
![](https://img.kancloud.cn/d3/ac/d3ac0bff3fd68c459dd266fe7b8297b0_1125x475.png)
string 数据结构,源码包 `src/runtime/string.go:stringStruct` 定义了string的数据结构:
```go
type stringStruct struct {
str unsafe.Pointer
len int
}
```
>[info]
> - stringStruct.str:字符串的首地址
> - stringStruct.len: 字符串的长度
## Unicode 转换 utf8
```go
var s rune
s = '曾'
fmt.Printf("字符'曾'对应的Unicode的十进制: %d\n", s)
fmt.Printf("字符'曾'对应的Unicode的十六进制: %x\n", s)
fmt.Printf("字符'曾'对应的Unicode的二进制: %b\n", s)
// 运行结果:
// 字符'曾'对应的Unicode的十进制: 26366
// 字符'曾'对应的Unicode的十六进制: 66fe
// 字符'曾'对应的Unicode的二进制: 110011011111110
```
Unicode二进制转换utf8二进制规则:`1110xxxx 10xxxxxx 10xxxxxx`
将Unicode最后六位补上utf8第三个字符的xxxxxx。将Unicode倒数7到12个字符补上utf第二个字符的xxxxxx。将Unicode剩下的数字补上utf8第一个字符(不够前面补0)
示例如下:
'曾'对应的Unicode二进制:110011011111110
'曾'对应的utf8二进制:11100110 10011011 10111110
验证
```go
s1 := "曾"
for i := 0; i < len(s1); i++ {
fmt.Printf("s1[%d]: %d, %b\n", i, s1[i], s1[i])
}
// 运行结果:
// s1[0]: 230, 11100110
// s1[1]: 155, 10011011
// s1[2]: 190, 10111110
```
## 字符串与字节串相互转换
```go
// 字符串与字节串相互转换
// (1) 字符串转字节串,有两种方式转换方式。
s4 := "abc,您好"
fmt.Println([]byte(s4)) // utf8 编码 【常用】
fmt.Println([]rune(s4)) // Unicode 编码
// (2) 字节串转字符串
b1 := []byte{97, 98, 99, 44, 230, 130, 168, 229, 165, 189}
b2 := []rune{97, 98, 99, 44, 24744, 22909}
fmt.Println(string(b1))
fmt.Println(string(b2))
// 运行结果:
// [97 98 99 44 230 130 168 229 165 189]
// [97 98 99 44 24744 22909]
// abc,您好
// abc,您好
```
## 统计字符串个数
```go
s5 := "abc,您好"
fmt.Printf("len: %v\n", len([]rune(s5)))
// 运行结果:
// len: 6
```
## for遍历字符串
```go
s3 := "您好呀!abc"
for i, v := range s3 {
fmt.Println(i, string(v))
}
// 运行结果:
// 0 您
// 3 好
// 6 呀
// 9 !
// 12 a
// 13 b
// 14 c
```
- Golang简介
- 开发环境
- Golang安装
- 编辑器及快捷键
- vscode插件
- 第一个程序
- 基础数据类型
- 变量及匿名变量
- 常量与iota
- 整型与浮点型
- 复数与布尔值
- 字符串
- 运算符
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 流程控制语句
- 获取用户输入
- if分支语句
- for循环语句
- switch语句
- break_continue_goto语法
- 高阶数据类型
- pointer指针
- array数组
- slice切片
- slice切片扩展
- map映射
- 函数
- 函数定义和调用
- 函数参数
- 函数返回值
- 作用域
- 函数形参传递
- 匿名函数
- 高阶函数
- 闭包
- defer语句
- 内置函数
- fmt
- strconv
- strings
- time
- os
- io
- 文件操作
- 编码
- 字符与字节
- 字符串
- 读写文件
- 结构体
- 类型别名和自定义类型
- 结构体声明
- 结构体实例化
- 模拟构造函数
- 方法接收器
- 匿名字段
- 嵌套与继承
- 序列化
- 接口
- 接口类型
- 值接收者和指针接收者
- 类型与接口对应关系
- 空接口
- 接口值
- 类型断言
- 并发编程
- 基本概念
- goroutine
- channel
- select
- 并发安全
- 练习题
- 第三方库
- Survey
- cobra