1 切片初始化

 func printSlice(s []int) {
fmt.Printf("len=%d cap=%d underlying array:%p, %v\n", len(s), cap(s), s, s)
} func sliceInit() { var s1 []int //声明s1,并没有初始化,此时s1是nil切片,没有分配底层数组
if s1 == nil {
fmt.Println("s1 is nil")
} s2 := []int{}
if s2 == nil {
fmt.Println("s2 is nil")
} s3 := make([]int, )
if s3 == nil {
fmt.Println("s3 is nil!")
} printSlice(s1)
printSlice(s2)
printSlice(s3)
}
func main(){
sliceInit()
}

Out:

s1 is nil
len= cap= underlying array:0x0, []
len= cap= underlying array:0x55c988, []
len= cap= underlying array:0x55c988, []

2 切片长度与容量

切片的长度就是它所包含的元素个数。

切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数

func main() {
s := []int{, , , , , }
printSlice(s) // Slice the slice to give it zero length.
s = s[:]
printSlice(s) // Extend its length.
s = s[:]
printSlice(s) // Drop its first two values.
s = s[:]
printSlice(s)
}

Out:

len= cap= underlying array:0xc04200a2a0, [     ]
len= cap= underlying array:0xc04200a2a0, []
len= cap= underlying array:0xc04200a2a0, [ ]
len= cap= underlying array:0xc04200a2b0, [ ]

3 赋值与传参

 func sliceT() {
arrayA := []int{, , , , }
fmt.Printf("arrayA: %p, %v\n", arrayA, arrayA)
fmt.Printf("arrayA: %p, %v\n", &arrayA, arrayA) fmt.Printf("arrayA: %p, %v\n", &arrayA[], arrayA)
fmt.Printf("arrayA: %p, %v\n", &arrayA[], arrayA)
fmt.Printf("arrayA: %p, %v\n", &arrayA[], arrayA)
fmt.Printf("arrayA: %p, %v\n", &arrayA[], arrayA)
fmt.Printf("arrayA: %p, %v\n", &arrayA[], arrayA) slice := arrayA[::]
fmt.Printf("slice: %p, %v\n", slice, slice)
fmt.Printf("slice: %p, %v\n", &slice[], slice)
fmt.Printf("slice: %p, %v\n", &slice[], slice) slice[] =
fmt.Printf("slice: %p, %v\n", slice, slice)
fmt.Printf("arrayA: %p, %v\n", &arrayA, arrayA) }

Out

 arrayA: %!p([]int=[    ]), [    ]
arrayA: 0xc04206c030, [ ]
arrayA: 0xc04206c030, [ ]
arrayA: 0xc04206c038, [ ]
arrayA: 0xc04206c040, [ ]
arrayA: 0xc04206c048, [ ]
arrayA: 0xc04206c050, [ ]
13 slice: 0xc04206c038, [ ]
14 slice: 0xc04206c038, [ ]
15 slice: 0xc04206c040, [ ]
slice: 0xc04206c038, [ ]
arrayA: 0xc04206c030, [ ]

2~4

一个数组变量表示整个数组,它不是指向第一个元素的指针(不像 C 语言的数组)因此数组名通过%p 无法打印地址。 当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组。 (为了避免复制数组,可以传递一个指向数组的指针)

6~9

int 在64机器上占8个字节

12~15

切片语法 a[ low:high:cap ]; cap 表示切片容量

切片名通过%p 打印,输出的是切片所引用的底层数组的地址

18~19

改变切片元素值就是改变其引用的数组的对应元素值

 func sliceT() {
s := []int{,,,,}
fmt.Printf("underlying array: %p, slice addr: %p\n", s, &s)
changeSlice(s)
fmt.Println(s)
} func changeSlice(s []int) {
fmt.Printf("underlying array: %p, param slice addr: %p\n", s, &s)
s[] = -
}

Out:

underlying array: 0xc04206c030, slice addr: 0xc04204a3a0
underlying array: 0xc04206c030, param slice addr: 0xc04204a400
[ - ]
 func sliceT1() {
s := []int{,,,,}
fmt.Printf("underlying array: %p, slice addr: %p\n", s, &s)
changeSlice1(s)
fmt.Println(s)
} func changeSlice1(s []int) {
fmt.Printf("underlying array: %p, param slice addr: %p\n", s, &s)
s = append(s, )
}

Out:

underlying array: 0xc04200a2a0, slice addr: 0xc0420023e0
underlying array: 0xc04200a2a0, param slice addr: 0xc042002440
[ ]

切片作为函数参数传递时是值传递,会拷贝一个切片,但形参和实参,拥有相同的底层数组引用。

更多内容: https://blog.go-zh.org/go-slices-usage-and-internals

https://www.jianshu.com/p/030aba2bff41

golang 切片小记的更多相关文章

  1. golang切片和数组的区别

    好久的没有写博客了,这段时间没事研究了下go这门语言. 我们先介绍下go中的数组和切片的区别和用法 说了这么多 我们先来看段代码吧 var arr1 [3]int var arr2 [3]int = ...

  2. golang切片slice

    切片slice是引用类型 len()函数获取元素的个数 cap()获取数组的容量 1.申明方式 (1)var a []int 与数组不同的是他不申明长度(2)s2 := make([]int, 3, ...

  3. golang切片数据结构解释

    1. 切片:切片是数组的一个引用,因此切片是引用类型 func main() { var arr = [6]int{1, 2, 3, 4, 5} var slice = arr[1:] fmt.Pri ...

  4. Golang切片的三种简单使用方式及区别

    概念 切片(slice)是建立在数组之上的更方便,更灵活,更强大的数据结构.切片并不存储任何元素而只是对现有数组的引用. 三种方式及细节案例 ①定义一个切片,然后让切片去引用一个已经创建好的数组 pa ...

  5. golang切片类型

    切片slice 其本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或全部 为引用类型 可以直接创建或从底层数组获取生成 使用len()获取元素个数,cap()获取容量 ...

  6. golang 切片和数组在for...range中的区别

    切片是引用类型,而数组是值类型,并且for...range有以下规则: range表达式只会在for语句开始执行时被求值一次,无论后边会有多少次迭代 range表达式的求值结果会被复制,也就是说,被迭 ...

  7. golang 切片和map查询比较

    package main import ( "fmt" "time" ) var testTimeSlice = []string{"aa" ...

  8. golang 切片扩容, 时间复杂度

    在切片扩容时,如果原来的底层数组足够大,能放的下 append 的数据,就不会新建底层数组.而如果不够的话,则会分配一个新的数组.也因此是 O(n) 的时间复杂度

  9. golang切片

    切片与数组 go的数组是这样的 array := [3]int{1,2,3} array := [...]int{1,2,3} go的切片 array := []int{1,2,3} //1 arra ...

随机推荐

  1. Mvnw 简介

    Mvnw 简介  8月 17, 2016 |  Nix.Huang 背景 maven是一款非常流行的java项目构建软件,它集项目的依赖管理.测试用例运行.打包.构件管理于一身,是我们工作的好帮手,m ...

  2. Azure 负载均衡器的多个 VIP

    您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn. Azure 负载均衡器 ...

  3. 无法打开项目文件“Web.csproj” 此安装不支持该项目类型

    今天把另外一个项目拷贝到我自己的机器上运行,发现突然打不开webapplication项目了,提示:无法打开项目文件“Web.csproj” 此安装不支持该项目类型.,就是那个网站,用度娘网上搜了一大 ...

  4. codeforces 963A Alternating Sum

    codeforces 963A Alternating Sum 题解 计算前 \(k\) 项的和,每 \(k\) 项的和是一个长度为 \((n+1)/k\) ,公比为 \((a^{-1}b)^k\) ...

  5. vs中添加工具cmder并自动定位到当前目录

    有时在vs中为了使用git命令行,需要打开cmder工具,并让cmder自切换到当前目录: 方法1: 看下效果: 方法2:在文件夹中右键(添加到右键自行百度)

  6. Windows和Linux环境,网络异常模拟测试方法【转载自光荣之路微信公众号】

    1.网络异常的分类 在系统的运行过程中,可能会遇到各种各样的网络问题,其中主要可能出现的问题有 网络延迟:当网络信息流过大时,可能导致设备反应缓慢,造成数据传输延迟: 网路掉包:网路掉包是在数据传输的 ...

  7. 二值形态学——腐蚀与膨胀 及 C语言代码实现

    参考文献:数字图像处理(第三版) 何东健 西安电子科技大学出版社 二值形态学中的运算对象是集合, 但实际运算中, 当涉及两个集合时并不把它们看作是互相对等的. 一般设A为图像集合, S为结构元素, 数 ...

  8. 【Git】本地与GitHub同步

    按步骤一步一步来,成功啦~ 以管理员身份运行Git-bash 要求输入用户名,密码 成功推入github~~加油加油 补充: 将仓库中的改动同步到本地 在git-bash中进入项目目录下,使用git ...

  9. 小米root

    ROOT之前,需要做几个准备工作: 首先,你需要去MIUI官网解锁,解锁教程见MIUI官网(百度搜索 MIUI解锁,第一个就是),然后根据官方指导进行解锁: 然后,因为MAX2的ROOT是卡刷,所以解 ...

  10. log4j 日志配置和jar包下载

    1.日志log4j文件配置 ${webapp.root}才是项目根目录log4j.appender.logfile.File= ${catalina.home}/log/filter.log 指生成日 ...