go string 实现

string

以后都在 github 更新,请戳go string 实现

目录

相关位置文件

内存构造

编码

更多资料

相关位置文件

  • src/runtime/string.go

内存构造

string 的内存构造比较简单

str 指向了 byte 数组的头部

len 存储了 string 的长度

layout

编码

package main

import "strconv"

func main() {
	var s string = "我是"
	for pos, val := range s {
		println(pos, val, strconv.FormatInt(int64(val), 16))
	}
	println(len(s), &s)
}

上述代码的运行结果如下

0 25105 6211
3 26159 662f
6 0xc000046768

对于字符串来说, range 会按照 UTF-8 格式进行解码并把每个unicode字符返回给你

0x6211 的 unicode 编码

0x662f 的 unicode 编码

我是utf-8 编码为 b'\xe6\x88\x91\xe6\x98\xaf'

package main

import (
	"strconv"
)

func main() {
	var s string = "我是"

	for pos, val := range []rune(s) {
		println(pos, strconv.FormatInt(int64(val), 16))
	}
	for pos, val := range []byte(s) {
		println(pos, strconv.FormatInt(int64(val), 16))
	}
}

上述代码的运行结果如下

0 6211
1 662f
0 e6
1 88
2 91
3 e6
4 98
5 af

从上述结果我们可以发现, rune 会遍历 string 中的每个 unicode 字符

byte 则会遍历 string 中的每个字节

并且 string 是以 utf-8 格式编码存储的

下图表示了 unicodeutf8 的区别(unicode 是一个字符映射标准, 表明了每个字符对应的码是多少, utf8 是一种编码方式, 它基于 unicode 进行压缩存储节省空间, 知道编解码方法后就可以存储和还原)

如果我们把 utf-8 格式中的标记位去除, 把红色部分的 bit 拼起来, 就还原除了 unicode 字符

对于不了解 utf-8 的同学, 当我们扫描第一个字节的时候, 在遇到第一个0之前, 统计有多少个连续的1, 这样就能知道存储当前这一个

nicode 字符用了多少个字节, 在当前的例子是 3, 那么就一共是 3 个字节, 除开开始的 10, 剩下的 bit 仍然存储了我们需要的信息

除开第一个字节的话, 剩下的字节都以 10 开头, 所以后面的两个字节, 排除前两个 bit, 也存了我们需要的信息

把需要的信息拼接起来, 就是我们的 unicode 字符

重复上述过程即可完成整个字符串的扫描

unicode

更多资料

Strings In Go’s Runtime

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值