1.定义

数组
var identifier [len]type
切片
var identifier []type

2.长度

Go 语言中的数组是一种 值类型(不像 C/C++ 中是指向首元素的指针),所以可以通过 new() 来创建: var arr1 = new([5]int)。 数组长度len(arr1)
切片(slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型
切片提供了计算容量的函数 cap() 可以测量切片最长可以达到多少:它等于切片的长度 + 数组除切片之外的长度。0 <= len(s) <= cap(s)

3.var arr1 = new([5]int) 和 var arr2 [5]int的区别

arr1 的类型是 *[5]int,而 arr2的类型是 [5]int

  1. package main
  2. import "fmt"
  3. func main(){
  4. var arr1 = new([5]int)
  5. var arr2 [5]int
  6. // f(arr1) //cannot use arr1 (type *[5]int) as type [5]int in argument to f
  7. //f(&arr1) //cannot use &arr1 (type **[5]int) as type [5]int in argument to f
  8. f(*arr1)
  9. fp(arr1)
  10. //fp(&arr1) //cannot use &arr1 (type **[5]int) as type *[5]int in argument to fp
  11. f(arr2)
  12. //fp(arr2) //cannot use arr2 (type [5]int) as type *[5]int in argument to fp
  13. fp(&arr2)
  14. }
  15. func f(a [5]int){
  16. fmt.Println(a)
  17. }
  18. func fp(a *[5]int){
  19. fmt.Println(a)
  20. }
  21. /**
  22. [0 0 0 0 0]
  23. &[0 0 0 0 0]
  24. [0 0 0 0 0]
  25. &[0 0 0 0 0]
  26. **/

4.数组常量,切片初始化

var arrKeyValue = [5]string{3: "Chris", 4: "Ron"}
var arrAge = [5]int{18, 20, 15, 22, 16}
var arrLazy = [...]int{5, 6, 7, 8, 22} ... 可以忽略

切片的初始化格式是:var slice1 []type = arr1[start:end]
var slice1 []type = arr1[:] 那么 slice1 就等于完整的 arr1 数组
arr1[2:] 和 arr1[2:len(arr1)] 相同,都包含了数组从第三个到最后的所有元素。
arr1[:3] 和 arr1[0:3] 相同,包含了从第一个到第三个元素(不包括第三个)。
一个由数字 1、2、3 组成的切片可以这么生成:s := [3]int{1,2,3}[:] 甚至更简单的 s := []int{1,2,3}。

5.多维数组、切片

数组通常是一维的,但是可以用来组装成多维数组,例如:[3][5]int,[2][2][2]float64。
和数组一样,切片通常也是一维的,但是也可以由一维组合成高维。通过分片的分片(或者切片的数组),长度可以任意动态变化,所以 Go 语言的多维切片可以任意切分。而且,内层的切片必须单独分配(通过 make 函数)。

6.将数组传递给函数

  • 传递数组的指针

    1. func main() {
    2. array := [3]float64{7.0, 8.5, 9.1}
    3. x := Sum(&array)
    4. }
    5. func Sum(a *[3]float64){}
  • 使用数组的切片 ``` func sum(a []int) int { s := 0 for i := 0; i < len(a); i++ {

    1. s += a[i]

    } return s }

func main() { var arr = [5]int{0, 1, 2, 3, 4} sum(arr[:]) }

  1. <a name="yoVYg"></a>
  2. #### 7.使用make创建切片,与new的区别
  3. make 的使用方式是:func make([]T, len, cap),其中 cap 是可选参数。<br />简写为 slice1 := make([]type, len)<br />s2 := make([]int, 10),那么 cap(s2) == len(s2) == 10

make([]int, 50, 100) new([100]int)[0:50]

  1. - new(T) 为每个新的类型T分配一片内存,初始化为 0 并且返回类型为*T的内存地址:这种方法 **返回一个指向类型为 T,值为 0 的地址的指针**,它适用于值类型如数组和结构体;它相当于 &T{}。
  2. - make(T) **返回一个类型为 T 的初始值**,它只适用于3种内建的引用类型:切片、map channel
  3. <a name="WvIpg"></a>
  4. #### 8.bytes包
  5. 类型 []byte 的切片十分常见,Go 语言有一个 bytes 包专门用来解决这种类型的操作方法。<br />**通过 buffer 串联字符串**<br />类似于 Java StringBuilder 类。<br />在下面的代码段中,我们创建一个 buffer,通过 buffer.WriteString(s) 方法将字符串 s 追加到后面,最后再通过 buffer.String() 方法转换为 string
  6. ```go
  7. package main
  8. import(
  9. "fmt"
  10. "bytes"
  11. )
  12. var strings = []string{"aaa","bbb","ccc"}
  13. var flag = 0
  14. func main(){
  15. var buffer bytes.Buffer
  16. for {
  17. if value, ok := getNextString(); ok {
  18. buffer.WriteString(value)
  19. } else {
  20. break
  21. }
  22. }
  23. fmt.Println(buffer.String())
  24. }
  25. func getNextString() (string, bool){
  26. if flag < len(strings){
  27. defer func (){ flag++ }()
  28. return strings[flag],true
  29. }
  30. return "",false
  31. }

9.for-range结构

  1. for ix, value := range slice1 {
  2. ...
  3. }
  4. //第一个返回值 ix 是数组或者切片的索引,第二个是在该索引位置的值

10.切片重组(reslice)

我们的切片在达到容量上限后可以扩容。改变切片长度的过程称之为切片重组 reslicing,做法如下:slice1 = slice1[0:end],其中 end 是新的末尾索引(即长度)

  1. //将切片扩展 1 位可以这么做
  2. sl = sl[0:len(sl)+1]
  1. var ar = [10]int{0,1,2,3,4,5,6,7,8,9}
  2. var a = ar[5:7] // reference to subarray {5,6} - len(a) is 2 and cap(a) is 5
  3. a = a[0:4] // ref of subarray {5,6,7,8} - len(a) is now 4 but cap(a) is still 5

11.切片的复制与追加

拷贝切片的 copy 函数和向切片追加新元素的 append 函数
func append(s[]T, x …T) []T 其中 append 方法将 0 个或多个具有相同类型 s 的元素追加到切片后面并且返回新的切片;追加的元素必须和原切片的元素同类型。如果 s 的容量不足以存储新增元素,append 会分配新的切片来保证已有切片元素和新增元素的存储。

  1. package main
  2. import "fmt"
  3. func main() {
  4. sl_from := []int{1, 2, 3}
  5. sl_to := make([]int, 10)
  6. n := copy(sl_to, sl_from)
  7. fmt.Println(sl_to)
  8. fmt.Printf("copied %d elements\n", n)
  9. sl3 := []int{1,2,3}
  10. sl3 = append(sl3, 4, 5, 6)
  11. fmt.Println(sl3)
  12. }

func copy(dst, src []T) int copy 方法将类型为 T 的切片从源地址 src 拷贝到目标地址 dst,覆盖 dst 的相关元素,并且返回拷贝的元素个数。源地址和目标地址可能会有重叠。拷贝个数是 src 和 dst 的长度最小值。如果 src 是字符串那么元素类型就是 byte。如果你还想继续使用 src,在拷贝结束后执行 src = dst。