早闻golang是utf-8存储的
可utf-8到底是什么,你知道么?过了这么久,我一直不知道什么是utf-8,今天学了一下。
go中如何存储 hello 世界?
str := "hello 世界"
我们可以先使用golang打印看看,当然不是平时那么打印,我们需要用到一些fmt的格式化工具包,我们按照unicode、字符串、二进制、十六进制这样来打印看看。
|
|
打印前转化成rune字符,打印之后如下
|
|
fmt能通过反射帮助我们把东西打印成想要的样子
%U可以打印成U+0068这种unicode形式%s就是普通的字符串打印%#b可以携带0b前导打印二进制字符串%#x可以携带0x前导打印十六进制字符,当然%#X可以以0X为前导,打印全大写十六进制字符
可是这些都是我们想要的格式,但是golang是如何存储的呢?
说到这里我们先来看看 string 是如何在 golang 中存储的。
|
|
在runtime中找到了对外呈现为string的stringStruct
为什么不能修改:看完这个结构你可能会有所感悟,gostring的内容没有在堆栈上,而是存在了.RODATE中
我们整理一下 golang 中的 runtime
|
|
go 中的 string 不像cpp中的那样,有自己的存储空间,而是一个指针指向.rodata数据区。
因此str[0] ="h"这种做法是不被允许的,可以想象如果多个string共用一个内存,那么对一个的修改当然会让另一个不可预测的修改,因此我们通常只能使用str="hello"这种方式,让string指向内存中新的位置,原来的string所占用的应该会被gc回收掉掉。
[]byte(string)这个动大家估计都用过,但是其实这个方法会开辟新的内存,我们可以从https://github.com/golang/go/blob/master/src/runtime/string.go#L165读取到源代码
|
|
你也可以使用一些骚版本,在不分配新内存的情况下直接修改它,使用一些runtime的不安全1的方法,
例如;
|
|
-
unsafe 这个包,大概就是比较接近内存的一些操作,容易在程序员不清楚自己在做什么时候造成崩溃。在论坛上有人给他换了个名字叫Believe me,笔者觉得比较形象。 ↩︎