前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 语言基础--string&数组&切片 浅析

Go 语言基础--string&数组&切片 浅析

作者头像
邹志全
发布2019-07-31 10:05:54
4770
发布2019-07-31 10:05:54
举报
文章被收录于专栏:EffectiveCodingEffectiveCoding

本篇来看一下go语言基本的一些复合结构,最常使用的复合结构有map、数组、切片这几个,string因为底层实现是一个[]byte所以大致可以理解为是一种数组结构,下面会从基础使用及底层实现来看一下这两个结构。

string

使用: go中字符串的字节采用UTF-8编码标识Unicode文本,关键字:string

代码语言:javascript
复制
var str string = "23333" // "" 用于定义一个单行字符串
var str string = `2333
                2333` // ``用于定义一个多行的字符串,内部进行原样解析

同其他语言一样,go中的string 也支持\r \n \t \' \" \\ \u*** 等转译字符。 并且我们可以使用数组的方式进行访问单个字符str[0] 跟Java类似,我们可以使用+来连接字符串,使用==,>,< 来比较字符串。 原理: 之前提到过string 实际上就是一个[]byte数组,但仅仅是粗略的说。实际上 string是一个引用类型,其中包含了两部分:指针(指向底层数组) + 数组长度。当发生复制时复制的也是指针和数组长度,底层的那个数组内容实际上是不发生变化的,这一点跟Java 还是蛮像的。 这里引用一篇blog,里面阐述了一下go string 的实现:

https://yq.aliyun.com/articles/656332?utm_content=m_1000019517

代码语言:javascript
复制
func boo(a int, b int)(int, string){
    return a + b, "abcd"
}
// 先找到main.boo
81079 000000000044dfa0 <main.boo>:
// 注意一下这一段
81087   44dfc0:>------48 8d 05 d4 eb 01 00 >--lea    0x1ebd4(%rip),%rax        # 46cb9b <go.string.*+0xbb>
81088   44dfc7:>------48 89 44 24 20       >--mov    %rax,0x20(%rsp)
81089   44dfcc:>------48 c7 44 24 28 04 00 >--movq   $0x4,0x28(%rsp)
81090   44dfd3:>------00 00- 
81091   44dfd5:>------c3                   >--retq---

lea 0x1ebd4(%rip),%rax得到char*, mov %rax,0x20(%rsp)复制给返回值, movq $0x4,0x28(%rsp)把长度也填进去,其实很轻松看到string就是c里面的char* 和len的组合。

数组

go语言中的数组也是一个具有唯一相同类型、已编号、且长度固定的数据序列(一段固定长度的连续内存区域)。 声明:var name []type

代码语言:javascript
复制
var array [5]int // 声明了一个长度为5的数组array
var array [...]string // 声明了一个暂不确定长度大小的string数组array

var array = [3]int{1, 2, 3} // 定义时指定长度,{}中的元素个数不能大于数组的长度
var array = [...]int{1, 2, 3}// 定义时不指定长度,有{}中的元素个数来确定数组的长度

注意点: [n]int[m]int[...]int不是一种类型,这个跟Java c/c++略有不同,大家可以粗暴的把数组长度也作为数组类型的一部分吧。

切片

go 中的切片和数组非常相像,就连声明和定义上也是类似的,可以简单粗暴的理解为不写长度就是一个切片,先来看一下差异:

代码语言:javascript
复制
var array [3]int // 这是一个数组
var slice []int // 这是一个切片
var array = [2]int{1, 2} // 这是一个数组
var slice = []int{1,2} // 这是一个切片

总体来说,可以把slice理解为一通动态数组,与Java 中的ArrayList 稍微有点像,底层就是一个数组,但是在数组的基础上加了一层抽象,变成非固定长度了。相对于数组,切片还有这种定义方式:

代码语言:javascript
复制
var slice []type = make([]type, len)
var slice []type = make([]type, length, capacity)

len指的是slice的长度(初始化长度),cap 为slice容量。 常用函数: len(): 求切片长度 cap(): 求切片容量(最长可以到达多少) append(): 向数组中追加元素,当出现数组长度不够用时,会进行数组的扩容(新开辟一段长度为*2 的连续内存空间以供使用) copy(): 切片copy demo:

代码语言:javascript
复制
func main() {
    srcSlice := []int{1, 2, 3}
    destSlice := []int{5, 5, 5, 5, 5, 5, 5}
    copy(destSlice, srcSlice)
    // destSlice =  [1 2 3 5 5 5 5]
    fmt.Println("destSlice = ", destSlice) 
}

注意点: 当你定义一个固定长度的slice时,go 会帮你初始化这个固定长度的元素,当执行append时,是追加 len + 1位的,而不是放到第一个,因为已经自动初始化的这几个固定长度的元素了。 这一篇暂时就这么多。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.07.10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • string
  • 数组
  • 切片
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档