Golang 基本类型字符串、数组和Slice

字符串String

字符串的底层表示

type StringHeader struct {
   
	Data uintptr
	Len int
}
  • Data 指向底层的字符数组
  • Len 表示字符串的长度

Go语言中,所有的文件都采用UTF-8编码,字符常量也是用的是UTF-8字符编码集。UTF-8 是可变长的编码方式,比如ASCII码 就用一个字节表示,中文就是3个字节表示。我记得ASCII的UTF-8编码是最高位为0。

使用range 轮询字符串,所出来的是utf-8编码的符文rune。比如"Hello你好",它轮询的时候,就是挨个输出H e l l o 你 好。

字符串与字节数组的转换

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

当a通过[]byte转换为b后,可能会觉得Go会把StringHeader.Data指向的字符数组地址直接给到b,但不是,因为string是不可修改的,所以StringHeader.Data指向的字符数组是不能直接拿出来修改的。所以这里就牵涉到了复制,当字符串长度大于32字节,还需要申请堆内存,所以牵涉到大字符串转换的时候,要考虑一下对内存的影响,比如日志的函数内部就不可能直接将字符串转换为[]byte数组。所以要考虑如何用指针就能将其弄出来呢?需要熟悉unsafe.Pointer 和 uintptr转换,可以看这篇文章Go指针的使用限制以及unsafe.Pointer的突破之路

这里,我们先把Slice的底层结构给出来

type SliceHeader struct {
   
	Data uintptr
	Len int
	Cap int
}

type StringHeader struct {
   
	Data uintptr
	Len int
}

 // 在了解Slice和String的底层结构表示后,也可以使用反射类型来构造
func string2bytes(s string) []byte {
   
    stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&s))
    bh := reflect.SliceHeader{
   
        Data: stringHeader.Data,
        Len: stringHeader.Len,
        Cap: stringHeader.Len,
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值