slice

注意,切片代表的窗口是无法向左扩展的
顺便提一下把切片的窗口向右扩展到最大的方法。对于s4来说,切片表达式s4[0:cap(s4)]就可以做到
一个切片的容量可以被看作是透过这个窗口最多可以看到的底层数组中元素的个数

切片并不是数组或数组指针,它通过内部指针和相关属性引用数组片段,以实现变长方案

slice并不是真正意义上的动态数组,而是一个引用类型.slice总是指向一个底层array, slice的声明也可以像array一样,只是不需要长度

可以把切片看做是对数组的一层简单的封装,因为在每个切片的底层数据结构中,一定会包含一个数组。数组可以被叫做切片的底层数组,而切片也可以被看作是对数组的某个连续片段的引用。

在这种情况下,切片的容量实际上代表了它的底层数组的长度

[low:high:max]
low起点
high终点(不包括此下标)
cap = max-low, 容量

func main() {a := []int{1, 2, 3, 4, 5}s := a[0:3:5]fmt.Println("s = ", s)//长度fmt.Println("len(s) = ", len(s))//容量fmt.Println("cap(s) = ", cap(s))
}

输出

s =  [1 2 3]
len(s) =  3
cap(s) =  5

多维的切片

[][]int{{10,20},{30}}

数组和切片的区别

func main() {a := [5]int{}fmt.Printf("len = %d, cap = %d\n", len(a), cap(a))s := []int{}fmt.Println(len(s), cap(s))s = append(s, 11)fmt.Printf("append: len = %d, cap = %d\n", len(s), cap(s))
}

输出

len = 5, cap = 5
0 0
append: len = 1, cap = 1

切片的创建

func main() {//自动推导类型,同时初始化s1 := []int{1, 2, 3, 4}fmt.Println("s1 = ", s1)//借助make函数,格式make(切片类型,长度,容量)s2 := make([]int, 5, 10)fmt.Println(len(s2), cap(s2))//没有指定容量,容量和长度一样s3 := make([]int, 5)fmt.Println(len(s3), cap(s3))
}

切片的截取

切片和底层数组的关系

会改变底层数组

func main() {a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}//新切片s1 := a[2:5]s1[1] = 666fmt.Println("s1 = ", s1)fmt.Println("a = ", a)//另外切片s2 := s1[2:7]s2[2] = 777fmt.Println("s2 = ", s2)fmt.Println("a = ", a)
}

输出

s1 =  [2 666 4]
a =  [0 1 2 666 4 5 6 7 8 9]
s2 =  [4 5 777 7 8]
a =  [0 1 2 666 4 5 777 7 8 9]

易错

一个切片是以另一个切片为基础切,容量一样那么都是指向同一个东西

func main() {data := []string{"red", "1", "black", "1", "pink", "red"}out := data[:1]for _, word := range data {fmt.Println("-----------")i:=0//比较取出的word是否在out中存在for ; i<len(out); i++ {if word == out[i] {fmt.Println(len(out))break}}if i== len(out) {out = append(out, word)fmt.Println(word)}}fmt.Println(data)fmt.Println(out)
}

append函数

会智能的底层数组的容量增长,一旦超过原底层数组容量,通常以2倍容量重新分配底层数组,并复制原来的数据

func main() {data := []string{"red", "1", "black", "1", "pink"}fmt.Printf("%v\n", data)out := data[:0]fmt.Printf("%v\n", out)for _, str := range data{if str != "1" {out = append(out, str)}}fmt.Printf("%v\n", data)   //感觉奇怪fmt.Printf("%v\n", out)//[red 1 black 1 pink]//[]//[red black pink 1 pink]//[red black pink]
}

如果不想里面有空的元素,就make的len为0,cap为0

slice := make([]string, 0)
slice = append(slice, "111")
slice = append(slice, "222")
slice = append(slice, "33")
for _, data := range slice {fmt.Println("data----", data)
}

slice:=append([]int{1,2,3},[]int{4,5,6}...)

fmt.Println(slice)//[1 2 3 4 5 6]

  • 还有种特殊用法,将字符串当作[]byte类型作为第二个参数传入

copy

copy会把一些位置替换

func main() {srcSlice := []int{1, 2}dstSlice := []int{6, 6, 6, 6, 6}copy(dstSlice, srcSlice)fmt.Println("dst = ", dstSlice)
}

输出

dst =  [1 2 6 6 6]

作为函数参数

是引用传递,里面改了,外面也一样会改

complexArray1 := [3][]string{[]string{"d", "e", "f"},[]string{"g", "h", "i"},[]string{"j", "k", "l"},
}

变量complexArray1是[3][]string类型的,也就是说,虽然它是一个数组,但是其中的每个元素又都是一个切片。这样一个值被传入函数的话,函数中对该参数值的修改会影响到complexArray1本身吗?

分2种情况,若是修改数组中的切片的某个元素,会影响原数组。若是修改数组的某个元素即a[1]=[]string{"x"}就不会影响原数组。谨记Go中都是浅拷贝,值类型和引用类型的区别

nil

目前已知只有var s []int这1种方法才是nil slice。其他情况都不是,因为只有no underlying array才是nil slice

下面几种方法都不是nil slice

  1. s := []int{}不是nil

  2. 删除所有元素也不算是nil,如

    sli = sli[:cap(sli)]
    sli = sli[len(sli):]
  3. make([]int, 0, 0)也不是nil

package mainimport "fmt"func main() {var a []intfmt.Println("a:", a, len(a), cap(a))b := []int{}fmt.Println("b:", b, len(b), cap(b))c := make([]int, 0, 0)fmt.Println("c:", c, len(c), cap(c))d := []int{2, 3, 5, 7, 11, 13}d = d[:cap(d)]d = d[len(d):]fmt.Println("d:", d, len(d), cap(d))if a == nil {fmt.Println("a is nil")}if b == nil {fmt.Println("b is nil")}if c == nil {fmt.Println("c is nil")}if d == nil {fmt.Println("d is nil")}
}

嵌套

slice可以嵌套包含slice,并且可以嵌套多层。也可以叫做多维slice。另外,array也支持多维array(这里就不提了)

嵌套一层

board1 := [][]string{[]string{"_", "_", "_"},[]string{"_", "_", "_"},[]string{"_", "_", "_"},
}

支持简写

比如上面这个例子可以改为

b := [][]string{{"_", "_", "_"},{"_", "_", "_"},{"_", "_", "_"},
}

嵌套两层

board2 := [][][]string{[][]string{[]string{"_", "_", "_"},[]string{"_", "_", "_"},[]string{"_", "_", "_"},},[][]string{[]string{"_", "_", "_"},[]string{"_", "_", "_"},[]string{"_", "_", "_"},},[][]string{[]string{"_", "_", "_"},[]string{"_", "_", "_"},[]string{"_", "_", "_"},},
}

赋值

board1[0][0] = "X"
board2[0][0][0] = "Y"

通过嵌套实现了高级数据结构,比如python中列表嵌套字典嵌套列表等等

golang中的切片相关推荐

  1. golang中的切片及内存拷贝

    十分钟讲明白, golang, Go 语言切片(Slice) 2017年08月21日 16:39:21 kingmax54212008 阅读数:8782 https://blog.csdn.net/k ...

  2. golang中slice切片的修改操作

    本文主要介绍go语言中切片slice的增删修改操作. 如果我们需要往切片中追加元素,可以使用内置的append()函数.这个函数接受一个需要被追加的切片,以及一个或者多个需要被追加的元素.如果我们需要 ...

  3. golang中slice切片使用的误区

    一.前言 最近在项目代码中,发现了一种写法,如下所示: //期望是能把id顺序写到切片,把切片占满,元素数为10个 Ids1 := make([]int64, 10) for _, v := rang ...

  4. golang中int类型切片无需传指针

    golang中int类型切片无需传指针就可以改变切片的值 func main() {x := []int{1, 2, 3}func(arr []int) {arr[0] = 7fmt.Println( ...

  5. golang修改结构体中的切片值

    golang修改结构体中的切片值,直接传结构体地址就可以 package mainimport "fmt"type rspInfo struct {KeyWords string ...

  6. golang中的二维数组和二维切片

    golang中数组和切片用的比较多,下面给个demo看看二维的数组和二维切片. package mainimport ("fmt" )func printarray(a [2][2 ...

  7. 如何在golang中关闭bufio.reader_Golang 并发模型系列:1. 轻松入门流水线模型

    Go语言中文网,致力于每日分享编码.开源等知识,欢迎关注我,会有意想不到的收获! Golang作为一个实用主义的编程语言,非常注重性能,在语言特性上天然支持并发,它有多种并发模型,通过流水线模型系列文 ...

  8. golang 数组和切片

    1.数组 golang中的数组是一种由固定长度和固定对象类型所组成的数据类型.例如下面: var a [4]int a是一个拥有4个int类型元素的数组.当a一旦被声明之后,元素个数就被固定了下来,在 ...

  9. golang中的strings.Split

    golang中的字符串操作strings.Split package mainimport ("fmt""strings" )//golang字符串操作 fun ...

最新文章

  1. React文档 state and lifecycle
  2. 在程序中设置最小化、最大化、关闭按钮
  3. (原创)对某国的一次渗透
  4. Idea的svn新建分支,切换分支,合并分支
  5. Android面试题整理
  6. VOSviewer | (二)入门-分析web of science
  7. Dell重装系统之官方原版系统
  8. 两球完全弹性碰撞反弹方向问题
  9. C++中endl的本质是什么
  10. 【css实现3D旋转卡片】
  11. zzulioj.1055 兔子繁殖问题
  12. Adobe 系列软件中英文版本的切换
  13. JS/SQL MVC框架介绍
  14. ubuntu护眼第二大神器 Redshift
  15. 腾讯发布“天眼云镜”主机安全产品
  16. 三面拼多多归来,我总结了这些面试题,希望能对你有用
  17. 好用的mac录屏软件推荐:白菜录屏mac中文免费版
  18. 绘画手残党的福音:涂鸦线稿秒变绝美图像
  19. OC网络:HTTP请求的常见方法
  20. mamp mysql启动失败_MAMP pro mysql 启动失败

热门文章

  1. 【Android 应用开发】 ActionBar 基础
  2. 【Android 应用开发】 Fragment 详解
  3. Python开发【第三篇】:Python基本数据类型
  4. 集合框架Map、List、Set
  5. 第 5 章 第二个 activity
  6. 等价类划分方法的应用
  7. JMS详细的工作原理
  8. Mule 官方例子研究
  9. 爱奇艺大数据分析平台的演进之路
  10. 火眼金睛算法,教你海量短文本场景下去重