iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >golang 中slice和string如何使用
  • 817
分享到

golang 中slice和string如何使用

2023-06-20 16:06:10 817人浏览 安东尼
摘要

这期内容当中小编将会给大家带来有关golang 中slice和string如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。slice 和 string 内部结构slice 和 string 的内部结

这期内容当中小编将会给大家带来有关golang 中slice和string如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

slice 和 string 内部结构

slice 和 string 的内部结构可以在 $GoROOT/src/reflect/value.go 里面找到

type StringHeader struct {    Data uintptr    Len  int}type SliceHeader struct {    Data uintptr    Len  int    Cap  int}

可以看到一个 string 包含一个数据指针和一个长度,长度是不可变的

slice 包含一个数据指针、一个长度和一个容量,当容量不够时会重新申请新的内存,Data 指针将指向新的地址,原来的地址空间将被释放

从这些结构就可以看出,string 和 slice 的赋值,包括当做参数传递,和自定义的结构体一样,都仅仅是 Data 指针的浅拷贝

slice 重用

append 操作
si1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}si2 := si1si2 = append(si2, 0)Convey("重新分配内存", func() {    header1 := (*reflect.SliceHeader)(unsafe.Pointer(&si1))    header2 := (*reflect.SliceHeader)(unsafe.Pointer(&si2))    fmt.Println(header1.Data)    fmt.Println(header2.Data)    So(header1.Data, ShouldNotEqual, header2.Data)})

si1 和 si2 开始都指向同一个数组,当对 si2 执行 append 操作时,由于原来的 Cap 值不够了,需要重新申请新的空间,因此 Data 值发生了变化,在 $GOROOT/src/reflect/value.go 这个文件里面还有关于新的 cap 值的策略,在 grow 这个函数里面,当 cap 小于 1024 的时候,是成倍的增长,超过的时候,每次增长 25%,而这种内存增长不仅仅数据拷贝(从旧的地址拷贝到新的地址)需要消耗额外的性能,旧地址内存的释放对 GC 也会造成额外的负担,所以如果能够知道数据的长度的情况下,尽量使用 make([]int, len, cap) 预分配内存,不知道长度的情况下,可以考虑下面的内存重用的方法

内存重用
si1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}si2 := si1[:7]Convey("不重新分配内存", func() {    header1 := (*reflect.SliceHeader)(unsafe.Pointer(&si1))    header2 := (*reflect.SliceHeader)(unsafe.Pointer(&si2))    fmt.Println(header1.Data)    fmt.Println(header2.Data)    So(header1.Data, ShouldEqual, header2.Data)})Convey("往切片里面 append 一个值", func() {    si2 = append(si2, 10)    Convey("改变了原 slice 的值", func() {        header1 := (*reflect.SliceHeader)(unsafe.Pointer(&si1))        header2 := (*reflect.SliceHeader)(unsafe.Pointer(&si2))        fmt.Println(header1.Data)        fmt.Println(header2.Data)        So(header1.Data, ShouldEqual, header2.Data)        So(si1[7], ShouldEqual, 10)    })})

si2 是 si1 的一个切片,从第一段代码可以看到切片并不重新分配内存,si2 和 si1 的 Data 指针指向同一片地址,而第二段代码可以看出,当我们往 si2 里面 append 一个新的值的时候,我们发现仍然没有内存分配,而且这个操作使得 si1 的值也发生了改变,因为两者本就是指向同一片 Data 区域,利用这个特性,我们只需要让 si1 = si1[:0] 就可以不断地清空 si1 的内容,实现内存的复用了

PS: 你可以使用 copy(si2, si1) 实现深拷贝

string

Convey("字符串常量", func() {    str1 := "hello world"    str2 := "hello world"    Convey("地址相同", func() {        header1 := (*reflect.StringHeader)(unsafe.Pointer(&str1))        header2 := (*reflect.StringHeader)(unsafe.Pointer(&str2))        fmt.Println(header1.Data)        fmt.Println(header2.Data)        So(header1.Data, ShouldEqual, header2.Data)    })})

这个例子比较简单,字符串常量使用的是同一片地址区域

Convey("相同字符串的不同子串", func() {    str1 := "hello world"[:6]    str2 := "hello world"[:5]    Convey("地址相同", func() {        header1 := (*reflect.StringHeader)(unsafe.Pointer(&str1))        header2 := (*reflect.StringHeader)(unsafe.Pointer(&str2))        fmt.Println(header1.Data, str1)        fmt.Println(header2.Data, str2)        So(str1, ShouldNotEqual, str2)        So(header1.Data, ShouldEqual, header2.Data)    })})

相同字符串的不同子串,不会额外申请新的内存,但是要注意的是这里的相同字符串,指的是 str1.Data == str2.Data && str1.Len == str2.Len,而不是 str1 == str2,下面这个例子可以说明 str1 == str2 但是其 Data 并不相同

Convey("不同字符串的相同子串", func() {    str1 := "hello world"[:5]    str2 := "hello golang"[:5]    Convey("地址不同", func() {        header1 := (*reflect.StringHeader)(unsafe.Pointer(&str1))        header2 := (*reflect.StringHeader)(unsafe.Pointer(&str2))        fmt.Println(header1.Data, str1)        fmt.Println(header2.Data, str2)        So(str1, ShouldEqual, str2)        So(header1.Data, ShouldNotEqual, header2.Data)    })})

上述就是小编为大家分享的golang 中slice和string如何使用了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网GO频道。

您可能感兴趣的文档:

--结束END--

本文标题: golang 中slice和string如何使用

本文链接: https://www.lsjlt.com/news/298217.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • golang 中slice和string如何使用
    这期内容当中小编将会给大家带来有关golang 中slice和string如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。slice 和 string 内部结构slice 和 string 的内部结...
    99+
    2023-06-20
  • Golang中Slice切片如何使用
    今天小编给大家分享一下Golang中Slice切片如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。上代码func&nb...
    99+
    2023-07-05
  • Golang中Slice使用源码分析
    本文小编为大家详细介绍“Golang中Slice使用源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang中Slice使用源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1、slice结构体首...
    99+
    2023-07-05
  • Golang中如何删除slice元素
    Golang是一种高效的编程语言,它有着强大的内存管理能力。在Golang开发中,我们经常会用到slice,它是Golang中最常用的数据结构之一。slice可以看作是一个动态数组,它有着灵活的大小和容量,因此在开发过程中非常方便。不过,处...
    99+
    2023-05-14
    slice go语言 Golang
  • Golang中的Slice底层如何实现
    这篇“Golang中的Slice底层如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Golang中的Slice底层如何...
    99+
    2023-07-05
  • 深入了解Golang中Slice切片的使用
    目录写在前面上代码分析原因总结写在前面 周日下午在家学习,看到一个关于切片的问题,在网上找了一些资料,做个总结。 上代码 func main() { sl := make([]in...
    99+
    2023-02-27
    Golang Slice切片使用 Golang Slice切片 Golang Slice
  • Go slice切片如何使用
    这篇文章主要介绍“Go slice切片如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Go slice切片如何使用”文章能帮助大家解决问题。定义切片区别于数组,是引用类型,...
    99+
    2023-07-02
  • Golang中Slice的分析与使用源码解析
    目录1、slice结构体2、slice初始化3、append操作4、slice截取5、slice深拷贝6、值传递还是引用传递参考文献1、slice结构体 首先我们来看一段代码 pac...
    99+
    2023-03-09
    go slice使用 go slice
  • jquery中slice方法如何用
    这篇文章主要讲解了“jquery中slice方法如何用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jquery中slice方法如何用”吧! ...
    99+
    2024-04-02
  • Golang中make和new如何使用
    本篇文章给大家分享的是有关Golang中make和new如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在golang中,make和ne...
    99+
    2024-04-02
  • Python中str.format()和f-string如何使用
    这篇文章主要介绍“Python中str.format()和f-string如何使用”,在日常操作中,相信很多人在Python中str.format()和f-string如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希...
    99+
    2023-07-05
  • Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?
    Golang 中 `array` 和 `slice{array,array,...}` 有什么区别?这是很多初学者常问的问题。php小编子墨为您解答:在Golang中,`array` ...
    99+
    2024-02-09
  • 使用golang怎么判断slice是否相等
    这期内容当中小编将会给大家带来有关使用golang怎么判断slice是否相等,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。slice相等的定义我们选择最常见的需求,也就是当两个slice的类型和长度相同,...
    99+
    2023-06-14
  • JavaScript中splice()和slice()有什么用
    这篇文章主要介绍了JavaScript中splice()和slice()有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1 splic...
    99+
    2024-04-02
  • 浅谈Golang Slice切片如何扩容的实现
    目录一、Slice数据结构是什么?二、详细代码1.数据结构2.扩容原则3.如何理解扩容规则一1.当小于1024个元素时2.当大于1024个元素时4.如何理解扩容规则二1.简单理解内存...
    99+
    2024-04-02
  • 如何使用Golang语言中的kafka和Sarama
    这篇文章给大家介绍如何使用Golang语言中的kafka和Sarama,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。01、介绍Apache Kafka 是一款开源的消息引擎系统。它在项...
    99+
    2024-04-02
  • golang中如何使用JSON
    今天小编给大家分享一下golang中如何使用JSON的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。JSON是一种通用的数据交...
    99+
    2023-07-06
  • Golang中如何使用 Iota
    这篇文章给大家介绍Golang中如何使用 Iota,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。如何实现枚举iota 是 Go 中预声明的一个特殊常量。它会被预声明为0,但是它的值在编译阶段并非是固定的,当预声明的 i...
    99+
    2023-06-15
  • golang中Error如何使用
    golang中Error如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Error是Go语言开发中最基础也是最重要的部分,跟其他语言的try catch的作用基本一致...
    99+
    2023-06-20
  • python如何使用slice函数命名切片
    小编给大家分享一下python如何使用slice函数命名切片,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!使用slice函数命名...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作