Golang 切片是动态数组还是胖指针? | 博客 | build-your-own.org

主要观点:切片(slice)具有指针、长度和容量三个字段,在不同使用场景下,切片要么是动态数组,要么是胖指针,二者是不兼容的概念,合并它们会导致错误。切片的操作存在一些令人惊讶的地方,如可超出长度进行切片、可修改容量字段等。

关键信息

  • 切片的容量字段用于指数增长方案,类似 C++ 的std::vector和 Python 的list
  • Golang 通过强制边界检查来改进 C 中越界错误的问题,切片索引会与长度进行检查。
  • 普通指针引用单个项目,胖指针引用一系列项目,切片不能既是动态数组又是胖指针。
  • 函数返回切片时,要明确其是动态数组还是胖指针,否则可能导致错误,如修改不应修改的内容或追加到不应追加的地方。
  • 可超出切片长度进行切片,结果由容量字段而非长度字段限制。
  • 存在修改容量字段的语法s[low:high:max],可用于移除多余容量,防止意外追加。

重要细节

  • 切片的指针指向数组数据,长度表示切片中的元素个数,容量表示切片可扩展的最大长度。
  • 在 Golang 中,不允许任意指针算术运算,许多普通指针用法被切片替代。
  • 动态数组拥有数据,是数据的唯一引用;胖指针不拥有数据,数据可能在其他地方被引用。
  • 超出切片长度进行切片时,结果受容量字段限制,这与索引单个项目的边界检查不同。
  • 修改容量字段的语法中,high - low为新长度,max - low为新容量,且只能减小容量。
阅读 8
0 条评论