go中string和slice no-copy转换
来源:互联网 发布:维港游客数据 编辑:程序博客网 时间:2024/06/05 21:06
在go里面,string和slice的互换是需要进行内存拷贝的,虽然在底层,它们都只是用 pointer + len来表示的一段内存。
通常,我们不会在意string和slice的转换带来的内存拷贝性能问题,但是总有些地方需要关注的,刚好在看vitess代码的时候,发现了一种很hack的做法,string和slice的转换只需要拷贝底层的指针,而不是内存拷贝。当然这样做的风险各位就要好好担当了:
func String(b []byte) (s string) { pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) pstring.Data = pbytes.Data pstring.Len = pbytes.Len return}func Slice(s string) (b []byte) { pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) pbytes.Data = pstring.Data pbytes.Len = pstring.Len pbytes.Cap = pstring.Len return}
在我的测试例子中,slice转string之后,如果slice的值有变化,string也会跟着改变,如下:
b := []byte("hello world")a := String(b)b[0] = 'a'println(a) //output aello world
但是string转slice之后,就不能更改slice了,如下:
a := "hello world"b := Slice(a)b[0] = 'a' //这里就等着崩溃吧//但是可以这样,因为go又重新给b分配了内存b = append(b, "hello world"…)
上面为什么会崩溃我猜想可能是string是immutable的,可能对应的内存地址也是不允许改动的。
另外,上面这个崩溃在defer里面是recover不回来的,真的就崩溃了,原因可能就跟c的非法内存访问一样,os不跟你玩了。
1 0
- go中string和slice no-copy转换
- go语言的string和slice是值拷贝吗?
- 关于 Go 中 Map 类型和 Slice 类型的传递
- Go语言中数组和slice的区别
- [go语言]slice和map
- go array和slice区别
- String类型中slice()、substr()和substring()方法的区别
- go slice
- Go-Slice
- go slice
- 【Go】slice
- Go语言中Slice(切片)初探
- 深入解析Go中Slice底层实现
- 如何从string 转换为const char *和char * (附带string中c_str()、data()、copy(p,n)函数的用法)
- go语言学习---数组和slice
- Go语言中的 Array, Slice和 Map
- go语言的array,slice和map
- Go语言中的 Array, Slice和 Map
- HDU 1879 继续畅通工程.
- 时对
- 第5周作业-打字成绩判断程序GUI(未完成)
- 勿用Windows 8取代Windows XP的十大理由
- Groovy---环境搭建
- go中string和slice no-copy转换
- php中break与continue的区别和用法举例
- NATIVE/ASCII编码互转- 站长工具
- EXCEL NO.列自动序列(+1)
- What is a Web Framework?
- ubuntu 下安装Opencv
- 云平台下制作虚拟机镜象img文件
- 更改XP串口号comX
- 苹果系列手机清除的文件如何恢复的呢