golang 源码分析之string

string
Go 语言中的字符串其实是一个只读的字节数组

string 对应的结构

type StringHeader struct {
	Data uintptr    //指向底层数据
	Len  int        //长度
}

type stringStruct struct {
	str unsafe.Pointer
	len int
}

字符串拼接
concatstrings:runtime/concatstrings

func concatstrings(buf *tmpBuf, a []string) string {
	idx := 0
	l := 0
	count := 0
	// 先把空的过滤了
	for i, x := range a {
		n := len(x)
		if n == 0 {
			continue
		}
		if l+n < l {
			throw("string concatenation too long")
		}
		l += n
		count++
		idx = i
	}
	if count == 0 {
		return ""
	}
	// 如果非空字符串的数量为 1 并且当前的字符串不在栈上就可以直接返回该字符串,不需要进行额外的任何操作
	if count == 1 && (buf != nil || !stringDataOnStack(a[idx])) {
		return a[idx]
	}
	// 申请新的内存
	s, b := rawstringtmp(buf, l)
	// 多个字符串拷贝到目标字符串所在的内存空间中
	for _, x := range a {
		copy(b, x)
		b = b[len(x):]
	}
	return s
}

字节数组到字符串的转换
slicebytetostring:runtime/slicebytetostring

func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) {
	if n == 0 {
		// 长度为0特殊处理
		return ""
	}
	// 长度为1 也特殊处理
	if n == 1 {
		p := unsafe.Pointer(&staticuint64s[*ptr])
		if sys.BigEndian {
			p = add(p, 7)
		}
		stringStructOf(&str).str = p
		stringStructOf(&str).len = 1
		return
	}

	var p unsafe.Pointer
	// 如果入参的缓冲区够用
	if buf != nil && n <= len(buf) {
		p = unsafe.Pointer(buf)
	} else {
		// 申请内存
		p = mallocgc(uintptr(n), nil, false)
	}
	// 复制
	stringStructOf(&str).str = p
	stringStructOf(&str).len = n
	// 移动
	memmove(p, unsafe.Pointer(ptr), uintptr(n))
	return
}

字符串转字节数组
stringtoslicebyte:runtime/stringtoslicebyte

func stringtoslicebyte(buf *tmpBuf, s string) []byte {
	var b []byte
	// 缓冲区够用
	if buf != nil && len(s) <= len(buf) {
		*buf = tmpBuf{}
		b = buf[:len(s)]
	} else {
		// 不够就申请内存
		b = rawbyteslice(len(s))
	}
	copy(b, s)
	return b
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值