Go中string与[]byte如何高效互转 |
您所在的位置:网站首页 › byte数组转二维数组 › Go中string与[]byte如何高效互转 |
前言
当我们使用go进行数据序列化或反序列化操作时,可能经常涉及到字符串和字节数组的转换。例如: if str, err := json.Marshal(from); err != nil { panic(err) } else { return string(str) }json序列化后为[]byte类型,需要将其转换为字符串类型。当数据量小时,类型间转换的开销可以忽略不计,但当数据量增大后,可能成为性能瓶颈,使用高效的转换方法能减少这方面的开销 数据结构在了解其如何转换前,需要了解其底层数据结构 本文基于go 1.13.12 string: type stringStruct struct { str unsafe.Pointer len int }slice: type slice struct { array unsafe.Pointer len int cap int }与slice的结构相比,string缺少一个表示容量的cap字段,因此不能对string遍历使用内置的cap()函数 那为什么string不需要cap字段呢?因为go中string被设计为不可变类型(当然在很多其他语言中也是), 由于其不可像slice一样追加元素,也就不需要cap字段判断是否超出底层数组的容量,来决定是否扩容 只有len属性不影响for-range等读取操作,因为for-range操作只根据len决定是否跳出循环 那为什么字符串要设定为不可变呢?因为这样能保证字符串的底层数组不发生改变 举个例子,map中以string为键,如果底层字符数组改变,则计算出的哈希值也会发生变化,这样再从map中定位时就找不到之前的value,因此其不可变特性能避免这种情况发生,string也适合作为map的键。除此之外,不可变特性也能保障数据的线程安全 常规实现字符串不可变有很多好处,为了维持其不可变特性,字符串和字节数组互转一般是通过数据拷贝的方式实现: var a string = "hello world" var b []byte = []byte(a) // string转[]byte a = string(b) // []byte转string这种方式实现简单,但是通过底层数据复制实现的,在编译期间分别转换成对slicebytetostring和stringtoslicebyte的函数调用 string转[]byte func stringtoslicebyte(buf *tmpBuf, s string) []byte { var b []byte if buf != nil && len(s) |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |