go 字符串string 和 字符数组[]byte 的高效转换

在我们的程序里面基本都写成如下的转换

var a = []byte("hello world")
var b = string(a)

这样的强制类型转换其实是调用底层的copy 函数进行转化,也就是说需要在内存中进行拷贝。这如果并发量达到千万级别,这样的转换是很耗性能的。

那么我们是否可以使用 unsafe.Point() 这样的指针直接转换呢?首先我们的知道 string 和 []byte 的底层表示方式。

string 的底层数组结构如下 
struct string {
unit8 *str
int len
}

而 []byte 的底层结构如下
struct uint8 {
unit8 *array
int len
int cap
}

通过对比 string 和 []byte 的结构体可知,[]byte 转换成 string 是可以直接使用 unsafe.Point(&b) 这样直接转换的。而string 则不可以直接转换成 []byte。 而需要构造把 string 的 str 指针赋值给 array 指针,把string 的 len 赋值给 []byte 的 len 和 cap.

高效的转换方法:

func bytes2str(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}


func str2bytes(s string) []byte {
	x := (*[2]uintptr)(unsafe.Pointer(&s)) // 获取s的起始地址开始后的两个 uintptr 指针
	h := [3]uintptr{x[0], x[1], x[1]}  // 构造三个指针数组
	return *(*[]byte)(unsafe.Pointer(&h))
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值