在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不跟你玩了。

go中string和slice no-copy转换的更多相关文章

  1. Java中String和byte[]间的转换浅析

    Java语言中字符串类型和字节数组类型相互之间的转换经常发生,网上的分析及代码也比较多,本文将分析总结常规的byte[]和String间的转换以及十六进制String和byte[]间相互转换的原理及实 ...

  2. Java中String和byte[]间的 转换浅析

    Java语言中字符串类型和字节数组类型相互之间的转换经常发生,网上的分析及代码也比较多,本文将分析总结常规的byte[]和String间的转换以及十六进制String和byte[]间相互转换的原理及实 ...

  3. C++11中string与数值类型的转换

    C++中string与数值类型的相互转换记录 string转int.double.long string s = "123.456"; // string -> int co ...

  4. Java中String和byte[]间的 转换

    数据库的字段中使用了blob类型时,在entity中此字段可以对应为byte[] 类型,保存到数据库中时需要把传入的参数转为byte[]类型,读取的时候再通过将byte[]类型转换为String类型. ...

  5. golang中string以及slice之间的一些问题

    好记性不如烂笔头o_O slice切片不会开辟新的空间 a := []int{0,1,2,3} b := make([]int, 8) b = a[:] b[2] = 9 fmt.Println(a) ...

  6. Swift 中 String 与 CChar 数组的转换

    在现阶段Swift的编码中,我们还是有很多场景需要调用一些C函数.在Swift与C的混编中,经常遇到的一个问题就是需要在两者中互相转换字符串.在C语言中,字符串通常是用一个char数组来表示,在Swi ...

  7. javascript中String 对象slice 和substring 区别

      1.slice(start,stop)和substring(start,stop)  方法都是用于提取字符串中从start开始到stop-1间的字符(因为字符串索引是从0开始).其中 start必 ...

  8. javascript中string与int之间的转换

    string转int javascript中提供了两种方法转换为数值(int): var str='15'; var str8='015'; var strChar='12abc'; //first ...

  9. Swift中String与NSDate的互相转换

    其实每种编程语言,我都觉得String和日期对象的相互转换是一种十分麻烦的事情,Swift也不例外.这篇博客记录了我学到的String与NSDate的互相转换方法,供大家参考. 从String转为NS ...

随机推荐

  1. [转] iOS使用NSMutableAttributedString 实现富文本(不同颜色字体、下划线等)

    转自: 在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线的需求.之前在网上找了一些资料,有的是重绘UILabel的textLayer,有的是用html5实现的,都 ...

  2. 文本输入框的两种div+css的写法

    1.扁平化的设计风格.--淘宝   直接使用input.对其设置height.padding.使鼠标居中又不会占满输入框.       2.背景是图片的设计.--百度   试用span将input包裹 ...

  3. RDLC报表上下标实现

    例:m的6次方 ="M"&ChrW(8310) Character Name Character Num Entity Hex Entity Superscript Cha ...

  4. Asp.net中实现同一用户名同时登陆,注销先前用户(转)

    Web 项目中经常遇到的问题就是同一用户名多次登陆的问题,相应的解决办法也很多,总结起来不外乎这几种解决办法:将登陆后的用户名放到数据库表中:登陆后的用 户名放到Session中:登陆后的用户名放到A ...

  5. iOS的Bundle资源束制作

    在静态库的制作中,很多时候我们的静态库也是带着文件,图片和多媒体资源的. 若只是直接加入到项目中也是可以,但是,考虑到方便管理(方便插件使用者的管理),我们希望把插件的资源文件打成一个包来管理. 当然 ...

  6. memcached真实项目中的应用

    上一篇memcached介绍及基本使用介绍了memcached的一些基本概念和一个范例.这一篇将介绍一个memcached在实际项目中的应用

  7. Mysql学习(慕课学习笔记5)约束

    约束类型: 1.NOT NULL (非空约束) 2.PRIMARY KEY(主键约束) 每张数据表只能存在一个主键 主键保证记录的唯一性 主键自动为NOT NULL (Auto_increment  ...

  8. Nutch的日志系统

    一.Nutch日志实现方式 1.Nutch使用slf4j作为日志接口,使用log4j作为具体实现.关于二者的基础,请参考 http://blog.csdn.net/jediael_lu/article ...

  9. jQuery中的插件的编写和使用

    1,常用的jQuery插件:表单验证插件formValidator a.目前支持5大验证方式:1.inputValidator(针对input,textarea,select控件的字符长度,值范围,选 ...

  10. LNMP环境出现”504 gateway time-out”错误的解决方案

    今天下午在调试测试VPS机器的时候,出现"504 gateway time-out"错误提示.VPS是安装的LNMP一键安装包,关于这个错误之前还没有见过,网上看到比较多的是502 ...