golang面试题:字符串转成byte数组,会发生内存拷贝吗?

问题

字符串转成byte数组,会发生内存拷贝吗?

怎么答

字符串转成切片,会产生拷贝。严格来说,只要是发生类型强转都会发生内存拷贝。那么问题来了。

频繁的内存拷贝操作听起来对性能不大友好。有没有什么办法可以在字符串转成切片的时候不用发生拷贝呢?

代码实现

go 复制代码
package main

import (
 "fmt"
 "reflect"
 "unsafe"
)

func main() {
 a :="aaa"
 ssh := *(*reflect.StringHeader)(unsafe.Pointer(&a))
 b := *(*[]byte)(unsafe.Pointer(&ssh))  
 fmt.Printf("%v",b)
}

解释

  • StringHeader 是字符串在go的底层结构。
go 复制代码
type StringHeader struct {
 Data uintptr
 Len  int
}
  • SliceHeader 是切片在go的底层结构。
go 复制代码
type SliceHeader struct {
 Data uintptr
 Len  int
 Cap  int
}
  • 那么如果想要在底层转换二者,只需要把 StringHeader 的地址强转成 SliceHeader 就行。那么go有个很强的包叫
    unsafe 。

1.unsafe.Pointer(&a)方法可以得到变量a的地址。

2.(reflect.StringHeader)(unsafe.Pointer(&a)) 可以把字符串a转成底层结构的形式。
3.(
[]byte)(unsafe.Pointer(&ssh)) 可以把ssh底层结构体转成byte的切片的指针。

4.再通过 *转为指针指向的实际内容。

相关推荐
都叫我大帅哥8 小时前
Docker Swarm 部署方案
后端
都叫我大帅哥8 小时前
在Swarm中部署Nacos并配置外部MySQL
后端
superman超哥8 小时前
Rust 异步错误处理最佳实践
开发语言·rust·编程语言·rust异步错误处理·rust最佳实践
脏脏a8 小时前
C++ STL list 模拟实现:从底层链表到容器封装
开发语言·c++·stl·双链表
想摆烂的不会研究的研究生15 小时前
每日八股——Redis(1)
数据库·经验分享·redis·后端·缓存
毕设源码-郭学长15 小时前
【开题答辩全过程】以 基于SpringBoot技术的美妆销售系统为例,包含答辩的问题和答案
java·spring boot·后端
故事不长丨15 小时前
C#正则表达式完全攻略:从基础到实战的全场景应用指南
开发语言·正则表达式·c#·regex
哈库纳玛塔塔16 小时前
放弃 MyBatis,拥抱新一代 Java 数据访问库
java·开发语言·数据库·mybatis·orm·dbvisitor
追逐时光者16 小时前
精选 10 款 .NET 开源免费、功能强大的 Windows 效率软件
后端·.net
追逐时光者16 小时前
一款开源、免费的 WPF 自定义控件集
后端·.net