go语言字符串系列

2,442 阅读2分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」。

前言

本文主要介绍字符串存储的数据结构,以及go语言如何实现字符串拼接操作。

字符串数据结构

type StringHeader struct {
   Data uintptr
   Len  int
}

需要注意的是,Data 字段不足以保证它引用的数据不会被垃圾回收,因此程序必须保留一个单独的、正确类型的指向底层数据的指针。

go语言开发者认为用字符来表示字符串的组成元素并不好,所以使用tune来代替,这里可以把tune理解为int32。

字符串的拼接操作

字符串分为常量和变量:常量的拼接发生在编译时,而字符串变量的拼接发生在运行时。根据字符串大小,go语言采用不同的内存分配策略。当拼接后的s字符串小于32字节时,会有一个临时的缓存供其使用。当拼接后的字符串大于32字节时,会请求在堆区分配内存。

常量拼接

  • 对两个字符串常量进行拼接时会调用noder.sum函数:将所有字符串常量append一个数组中,然后对数据进行拼接。
  • 在函数遍历阶段,walkexpr函数会决定具体使用运行时的哪一个拼接函数。walkexpr函数调用了addstr(n,init),当拼接数量小于或等于5时,调用运行时concatstring1~concatstring5中对应的函数。当字符串的数量大于5时,调用运行时concatstrings函数,并且将字符串通过切片传入。

变量拼接

运行时对字符串变量拼接并不是简单地将一个字符串合并到另一个字符串中,而是开辟一个更大的内存,并通过内存复制的方式将字符串复制到其中。