早闻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,笔者觉得比较形象。 ↩︎