学习笔记——数组和切片

  

参考极客时间:https://time.geekbang.org/column/article/14106

  

1,数组(数组)类型和切片(片)类型区别是什么?

  

数组类型的值(以下简称数组)的长度是固定的,而切片类型的值(以下简称切片)是可变长的。

  

数组的长度在声明它的时候就必须给定,并且之后不会再改变。可以说,数组的长度是其类型的一部分,比如,字符串[1]和[2]字符串就是两个不同的数组类型。而切片的类型字面量中只有元素的类型,而没有长度。切片的长度可以自动地随着其中元素数量的增长而增长,但不会随着元素数量的减少而减小。
学习笔记——数组和切片

  

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

  

去语言的切片类型属于<强>引用类型强,同属引用类型的还有字典类型,通道类型,函数类型等;而去语言的数组类型则属于<强>值类型强,同属值类型的有基础数据类型以及结构体类型。

  

去语言里不存在像Java等编程语言中令人困惑的“传值或传引用“问题。在去语言中,我们判断所谓的“传值”或者”传引用“只要看被传递的值的类型就好了。如果传递的值是引用类型的,那么就是“传引用”。如果传递的值是值类型的,那么就是“传值”。从传递成本的角度讲,引用类型的值往往要比值类型的值低很多。

  

我们在数组和切片之上都可以应用索引表达式,得到的都会是某个元素。我们在它们之上也都可以应用切片表达式,也都会得到一个新的切片。

  

调用内建函数len,得到数组和切片的长度。通过调用内建函数帽,我们可以得到它们的容量。但要注意,<强>数组的容量永远等于其长度,都是不可变的强。切片的容量却不是这样,并且它的变化是有规律可寻的。

  

2,怎样正确估算切片的长度和容量?

  
 <代码>包主要
  
  进口“fmt”
  
  函数main () {//示例1。
  s1:=(int [], 5)
  fmt。Printf (" s1的长度:% d \ n”, len (s1))
  fmt。Printf (" s1的能力:% d \ n”,帽(s1))
  fmt。Printf (" s1的价值:% d \ n”, s1)
  s2:=(int [] 5 8)
  fmt。Printf("的长度s2: % d \ n”, len (s2))
  fmt。Printf (" s2的能力:% d \ n”,帽(s2))
  fmt。Printf("的价值s2: % d \ n”, s2)
  fmt.Println()  
  
 <代码> demo15.go跑去
  s1的长度:5
  s1:能力5
  s1:的价值(0 0 0 0 0)
  s2的长度:5
  s2:能力8
  s2:的值(0 0 0 0 0) 
  

我用内建函数使声明了一个int[]类型的变量s1。我传给使函数的第二个参数是5,从而指明了该切片的长度。我用几乎同样的方式声明了切片s2,只不过多传入了一个参数8以指明该切片的容量。现在,具体的问题是:切片s1和s2的容量都是多少吗?

  

这道题的典型回答:切片s1和s2的容量分别是5和8。
s1的容量为什么是5呢?因为我在声明s1的时候把它的长度设置成了5。当我们用使函数初始化切片时,如果不指明其容量,那么它就会和长度一致。如果在初始化时指明了容量,那么切片的实际容量也就是它了。这也正是s2的容量是8的原因。

  

过s2再来明确下长度,容量以及它们的关系。我在初始化s2代表的切片时,同时也指定了它的长度和容量。我在刚才说过,可以把切片看做是对数组的一层简单的封装,因为在每个切片的底层数据结构中,一定会包含一个数组。数组可以被叫做切片的底层数组,而切片也可以被看作是对数组的某个连续片段的引用。在这种情况下,切片的容量实际上代表了它的底层数组的长度,这里是8。(注意,切片的底层数组等同于我们前面讲到的数组,其长度不可变。)

  

<强>有一个窗口,你可以通过这个窗口看到一个数组,但是不一定能看到该数组中的所有元素,有时候只能看到连续的一部分元素。

  

这个数组就是切片s2的底层数组,而这个<强>窗口强就是切片s2本身.s2的<强>长度强实际上指明的就是这个窗口的<强>宽度强,决定了你透过s2,可以看到其底层数组中的哪<强>几个连续的元素强。由于s2的长度是5,所以你可以看到底层数组中的第1个元素到第5个元素,对应的底层数组的索引范围是[0,4]。切片代表的窗口也会被划分成一个一个的小格子,就像我们家里的窗户那样。每个小格子都对应着其底层数组中的某一个元素。

学习笔记——数组和切片