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. webpack笔记一 起步

    webpack笔记一 起步 安装 对于大多数项目,我们建议本地安装(--save-dev).这可以在引入突破式变更(breaking change)版本时,更容易分别升级项目. 起步 初始化项目 mk ...

  2. Java学习---Java代码编写规范

    编码规范 1 前言为确保系统源程序可读性,从而增强系统可维护性,java编程人员应具有基本类似的编程风格,兹制定下述Java编程规范,以规范系统Java部分编程.系统继承的其它资源中的源程序也应按此规 ...

  3. Java学习---RMI 技术分析[Hessian]

    一.什么是Hessian Hessian 是一个基于 binary-RPC 实现的远程通讯 library.使用二进制传输数据.Hessian通常通过Web应用来提供服务,通过接口暴露.Servlet ...

  4. 沉淀再出发:ElasticSearch的中文分词器ik

    沉淀再出发:ElasticSearch的中文分词器ik 一.前言   为什么要在elasticsearch中要使用ik这样的中文分词呢,那是因为es提供的分词是英文分词,对于中文的分词就做的非常不好了 ...

  5. JavaScript 学习总结

    JavaScript学习总结 1.JavaScript基础介绍 2.JavaScript基础-数据类型 3.JavaScript基础-运算符与基础程序设计 Break:结束当前循环,不再进行下一次循环 ...

  6. 并发集合 System.Collections.Concurrent 命名空间

    System.Collections.Concurrent 命名空间提供多个线程安全集合类. 当有多个线程并发访问集合时,应使用这些类代替 System.Collections 和 System.Co ...

  7. Glance组件解析

    1 Glance基本框架图 组件 描述 A client 任何使用Glance服务的应用. REST API 通过REST方式暴露Glance的使用接口. Database Abstraction L ...

  8. URAL-1019 Line Painting----暴力或线段树

    题目链接: https://cn.vjudge.net/problem/URAL-1019 题目大意: 一个0~1e9的区间,初始都是白的,现进行N次操作,每次将一段区间图上一中颜色.最后问说连续最长 ...

  9. vim基础初步

    vim文本编辑器初步 一.跟vi编辑器的关系 可以说vim编辑器是vi编辑器的升级版,它保留了vi编辑器的所有东西,而且加入了自己的新的特性. 比如说:支持跨平台,支持语法高亮,支持多级撤销等. ++ ...

  10. (六)Linux下的压缩命令

    ======================================================================================== .zip格式的压缩和解 ...