Golang 中的数组与切片
2022-4-14 23:56:41 Author: mp.weixin.qq.com(查看原文) 阅读量:3 收藏

0x00 数组

  • 声明数组的方式
  • 固定长度的数组在传递参数时需严格匹配数组类型、长度
  • 函数的形参为数组时,其拷贝方式为值拷贝
package main

import (
 "fmt"
)

func printArray(myArray [4]int) {
 // 值拷贝
 for index, value := range myArray {
  fmt.Println("index = ", index, " , value = ", value)
 }

 myArray[0] = 233
}

func main() {

 // 固定长度数组
 var myArray1 [10]int
 var myArray2 [10]float32

 myArray3 := [10]int{1, 2, 3, 4}

 myArray4 := [4]int{11, 22, 33, 44}

 // for i := 0; i < 10; i ++ {
 for i := 0; i < len(myArray1); i++ {
  fmt.Println(myArray1[i])

 }

 fmt.Println("===== ===== ===== =====")

 for j := 0; j < len(myArray2); j++ {
  fmt.Println(myArray2[j])
 }

 fmt.Println("===== ===== ===== =====")

 for index, value := range myArray3 {
  fmt.Println("index= ", index, ", value = ", value)
 }

 // 查看数组的数据类型
 fmt.Printf("myArray1 types = %T\n", myArray1)
 fmt.Printf("myArray2 types = %T\n", myArray2)
 fmt.Printf("myArray3 types = %T\n", myArray3)
 fmt.Printf("myArray4 types = %T\n", myArray4)

 fmt.Println("===== ===== ===== =====")

 printArray(myArray4)

 fmt.Println("=====")

 for index, value := range myArray4 {
  fmt.Println("index = ", index, ", value = ", value)
 }
}

image
image

0x01 slice

  • slice 切片,动态数组。
  • 在定义函数时,我们通常希望形参的数据类型更通用,数组是固定长度的,slice 切片是动态数组,形参直接定义为 slice 即可。
  • 动态数组在函数传参时为引用传递
  • 不同元素长度的动态数组,传参的形参是一致的
package main

import (
 "fmt"
)

// func printArray(myArray [4]int) {
//  // 值拷贝
//  for index, value := range myArray {
//   fmt.Println("index = ", index, " , value = ", value)
//  }

//  myArray[0] = 233
// }

func printSlice(myArray []int) {
 // 引用传递
 // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
 // 动态数组是指向数组内存的指针(引用)
 for _, value := range myArray {
  fmt.Println("value = ", value)
 }
 myArray[0] = 233
}

func main() {

 // // 固定长度数组
 // var myArray1 [10]int
 // var myArray2 [10]float32

 // myArray3 := [10]int{1, 2, 3, 4}

 // myArray4 := [4]int{11, 22, 33, 44}

 // // for i := 0; i < 10; i ++ {
 // for i := 0; i < len(myArray1); i++ {
 //  fmt.Println(myArray1[i])

 // }

 // fmt.Println("===== ===== ===== =====")

 // for j := 0; j < len(myArray2); j++ {
 //  fmt.Println(myArray2[j])
 // }

 // fmt.Println("===== ===== ===== =====")

 // for index, value := range myArray3 {
 //  fmt.Println("index= ", index, ", value = ", value)
 // }

 // // 查看数组的数据类型
 // fmt.Printf("myArray1 types = %T\n", myArray1)
 // fmt.Printf("myArray2 types = %T\n", myArray2)
 // fmt.Printf("myArray3 types = %T\n", myArray3)
 // fmt.Printf("myArray4 types = %T\n", myArray4)

 // fmt.Println("===== ===== ===== =====")

 // printArray(myArray4)

 // fmt.Println("=====")

 // for index, value := range myArray4 {
 //  fmt.Println("index = ", index, ", value = ", value)
 // }
 // var myArray5 [10]int
 myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
 fmt.Printf("myArray type is %T\n", myArray)

 printSlice(myArray)

 fmt.Println("===== ===== ===== =====")

 // printSlice(myArray5)

 for _, value := range myArray {
  fmt.Println("value = ", value)
 }
}

image

0x02 slice 的 4 种声明定义方式

package main

import (
 "fmt"
)

// func printArray(myArray [4]int) {
//  // 值拷贝
//  for index, value := range myArray {
//   fmt.Println("index = ", index, " , value = ", value)
//  }

//  myArray[0] = 233
// }

// func printSlice(myArray []int) {
//  // 引用传递
//  // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
//  // 动态数组是指向数组内存的指针(引用)
//  for _, value := range myArray {
//   fmt.Println("value = ", value)
//  }
//  myArray[0] = 233
// }

func main() {

 // // 固定长度数组
 // var myArray1 [10]int
 // var myArray2 [10]float32

 // myArray3 := [10]int{1, 2, 3, 4}

 // myArray4 := [4]int{11, 22, 33, 44}

 // // for i := 0; i < 10; i ++ {
 // for i := 0; i < len(myArray1); i++ {
 //  fmt.Println(myArray1[i])

 // }

 // fmt.Println("===== ===== ===== =====")

 // for j := 0; j < len(myArray2); j++ {
 //  fmt.Println(myArray2[j])
 // }

 // fmt.Println("===== ===== ===== =====")

 // for index, value := range myArray3 {
 //  fmt.Println("index= ", index, ", value = ", value)
 // }

 // // 查看数组的数据类型
 // fmt.Printf("myArray1 types = %T\n", myArray1)
 // fmt.Printf("myArray2 types = %T\n", myArray2)
 // fmt.Printf("myArray3 types = %T\n", myArray3)
 // fmt.Printf("myArray4 types = %T\n", myArray4)

 // fmt.Println("===== ===== ===== =====")

 // printArray(myArray4)

 // fmt.Println("=====")

 // for index, value := range myArray4 {
 //  fmt.Println("index = ", index, ", value = ", value)
 // }
 // var myArray5 [10]int
 // myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
 // fmt.Printf("myArray type is %T\n", myArray)

 // printSlice(myArray)

 // fmt.Println("===== ===== ===== =====")

 // // printSlice(myArray5)

 // for _, value := range myArray {
 //  fmt.Println("value = ", value)
 // }

 // 声明 slice 的 4 种方法

 // 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
 slice1 := []int{1, 2, 3}
 fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)

 // 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
 // 此时无法为 slice2[0] = 1 赋值,会提示越界错误
 var slice2 []int

 // 可以通过 make 开辟内存空间
 slice2 = make([]int, 3)
 slice2[0] = 233
 fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)

 // 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
 var slice3 []int = make([]int, 3)
 fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3) 

 // 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
 slice4 := make([]int, 4)
 fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)

 // 判断 slice 是否为空
 var slice5 []int
 if slice5 == nil {
  fmt.Println("slice5 is nil,是一个空切片")
 } else {
  fmt.Println("slice5 是有空间的")
 }

}

image

0x03 slice 切片容量的追加

切片的长度(len)和容量(cap)不同,长度表示左指针及右指针之间的距离,容量表示左指针至底层数组末尾的距离。

image

切片的扩容机制,append() 的时候,如果长度增加后超过容量,则将容量增加 2 倍。

package main

import (
 "fmt"
)

// func printArray(myArray [4]int) {
//  // 值拷贝
//  for index, value := range myArray {
//   fmt.Println("index = ", index, " , value = ", value)
//  }

//  myArray[0] = 233
// }

// func printSlice(myArray []int) {
//  // 引用传递
//  // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
//  // 动态数组是指向数组内存的指针(引用)
//  for _, value := range myArray {
//   fmt.Println("value = ", value)
//  }
//  myArray[0] = 233
// }

func main() {

 // // 固定长度数组
 // var myArray1 [10]int
 // var myArray2 [10]float32

 // myArray3 := [10]int{1, 2, 3, 4}

 // myArray4 := [4]int{11, 22, 33, 44}

 // // for i := 0; i < 10; i ++ {
 // for i := 0; i < len(myArray1); i++ {
 //  fmt.Println(myArray1[i])

 // }

 // fmt.Println("===== ===== ===== =====")

 // for j := 0; j < len(myArray2); j++ {
 //  fmt.Println(myArray2[j])
 // }

 // fmt.Println("===== ===== ===== =====")

 // for index, value := range myArray3 {
 //  fmt.Println("index= ", index, ", value = ", value)
 // }

 // // 查看数组的数据类型
 // fmt.Printf("myArray1 types = %T\n", myArray1)
 // fmt.Printf("myArray2 types = %T\n", myArray2)
 // fmt.Printf("myArray3 types = %T\n", myArray3)
 // fmt.Printf("myArray4 types = %T\n", myArray4)

 // fmt.Println("===== ===== ===== =====")

 // printArray(myArray4)

 // fmt.Println("=====")

 // for index, value := range myArray4 {
 //  fmt.Println("index = ", index, ", value = ", value)
 // }
 // var myArray5 [10]int
 // myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
 // fmt.Printf("myArray type is %T\n", myArray)

 // printSlice(myArray)

 // fmt.Println("===== ===== ===== =====")

 // // printSlice(myArray5)

 // for _, value := range myArray {
 //  fmt.Println("value = ", value)
 // }

 // // 声明 slice 的 4 种方法

 // // 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
 // slice1 := []int{1, 2, 3}
 // fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)

 // // 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
 // // 此时无法为 slice2[0] = 1 赋值,会提示越界错误
 // var slice2 []int

 // // 可以通过 make 开辟内存空间
 // slice2 = make([]int, 3)
 // slice2[0] = 233
 // fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)

 // // 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
 // var slice3 []int = make([]int, 3)
 // fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3)

 // // 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
 // slice4 := make([]int, 4)
 // fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)

 // // 判断 slice 是否为空
 // var slice5 []int
 // if slice5 == nil {
 //  fmt.Println("slice5 is nil,是一个空切片")
 // } else {
 //  fmt.Println("slice5 是有空间的")
 // }

 // slice 切片的长度是 3,容量是 5
 var slice6 = make([]int, 3, 5)

 fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // 向 slice6 中添加元素 1,此时 len = 4,cap = 5,[0 0 0 1]
 slice6 = append(slice6, 1)

 fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 slice6 = append(slice6, 2)
 fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // 像一个 slice 容量满了的 slice 中追加元素,Golang 会在底层开辟一定量等长的内存空间,如 原来的容量是 5,则现在的容量为 10
 // cap = 10
 slice6 = append(slice6, 3)
 fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 fmt.Println("===== ===== ===== ===== =====")

 // 如果没指定 cap,则 cap = len
 var number2 = make([]int, 3)
 fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)

 // cap = 6
 number2 = append(number2, 111)
 fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)

}

image

0x04 slice 切片容量的截取

slice 截取后,两个 slice 仍然指向相同的内存空间。可以通过 copy() 函数,将两个 slice 指向不同的内存空间。(深拷贝,拷贝一个副本,将底层数组的 slice 一起进行拷贝。)

package main

import (
 "fmt"
)

// func printArray(myArray [4]int) {
//  // 值拷贝
//  for index, value := range myArray {
//   fmt.Println("index = ", index, " , value = ", value)
//  }

//  myArray[0] = 233
// }

// func printSlice(myArray []int) {
//  // 引用传递
//  // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
//  // 动态数组是指向数组内存的指针(引用)
//  for _, value := range myArray {
//   fmt.Println("value = ", value)
//  }
//  myArray[0] = 233
// }

func main() {

 // // 固定长度数组
 // var myArray1 [10]int
 // var myArray2 [10]float32

 // myArray3 := [10]int{1, 2, 3, 4}

 // myArray4 := [4]int{11, 22, 33, 44}

 // // for i := 0; i < 10; i ++ {
 // for i := 0; i < len(myArray1); i++ {
 //  fmt.Println(myArray1[i])

 // }

 // fmt.Println("===== ===== ===== =====")

 // for j := 0; j < len(myArray2); j++ {
 //  fmt.Println(myArray2[j])
 // }

 // fmt.Println("===== ===== ===== =====")

 // for index, value := range myArray3 {
 //  fmt.Println("index= ", index, ", value = ", value)
 // }

 // // 查看数组的数据类型
 // fmt.Printf("myArray1 types = %T\n", myArray1)
 // fmt.Printf("myArray2 types = %T\n", myArray2)
 // fmt.Printf("myArray3 types = %T\n", myArray3)
 // fmt.Printf("myArray4 types = %T\n", myArray4)

 // fmt.Println("===== ===== ===== =====")

 // printArray(myArray4)

 // fmt.Println("=====")

 // for index, value := range myArray4 {
 //  fmt.Println("index = ", index, ", value = ", value)
 // }
 // var myArray5 [10]int
 // myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
 // fmt.Printf("myArray type is %T\n", myArray)

 // printSlice(myArray)

 // fmt.Println("===== ===== ===== =====")

 // // printSlice(myArray5)

 // for _, value := range myArray {
 //  fmt.Println("value = ", value)
 // }

 // // 声明 slice 的 4 种方法

 // // 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
 // slice1 := []int{1, 2, 3}
 // fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)

 // // 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
 // // 此时无法为 slice2[0] = 1 赋值,会提示越界错误
 // var slice2 []int

 // // 可以通过 make 开辟内存空间
 // slice2 = make([]int, 3)
 // slice2[0] = 233
 // fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)

 // // 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
 // var slice3 []int = make([]int, 3)
 // fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3)

 // // 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
 // slice4 := make([]int, 4)
 // fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)

 // // 判断 slice 是否为空
 // var slice5 []int
 // if slice5 == nil {
 //  fmt.Println("slice5 is nil,是一个空切片")
 // } else {
 //  fmt.Println("slice5 是有空间的")
 // }

 // // slice 切片的长度是 3,容量是 5
 // var slice6 = make([]int, 3, 5)

 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // // 向 slice6 中添加元素 1,此时 len = 4,cap = 5,[0 0 0 1]
 // slice6 = append(slice6, 1)

 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // slice6 = append(slice6, 2)
 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // // 像一个 slice 容量满了的 slice 中追加元素,Golang 会在底层开辟一定量等长的内存空间,如 原来的容量是 5,则现在的容量为 10
 // // cap = 10
 // slice6 = append(slice6, 3)
 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // fmt.Println("===== ===== ===== ===== =====")

 // // 如果没指定 cap,则 cap = len
 // var number2 = make([]int, 3)
 // fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)

 // // cap = 6
 // number2 = append(number2, 111)
 // fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)

 // len = 3, cap = 3
 s := []int{111, 222, 333}

 // 左闭右开 [0, 1)
 s1 := s[0:1]

 fmt.Printf("s1 = %v \n", s1)

 // [0, 2) [111, 222]
 s2 := s[0:2]
 fmt.Printf("s2 = %v \n", s2)

 // 表示截取全部元素
 s3 := s[:]
 fmt.Printf("s3 = %v \n", s3)

 // 默认下限为 0, [111 222]
 s4 := s[:2]
 fmt.Printf("s4 = %v \n", s4)

 // 默认上限为 len()  [222 333]

 s5 := s[1:]
 fmt.Printf("s5 = %v \n", s5)

 // slice 截取后,两个 slice 仍然指向相同的内存空间
 s1[0] = 888
 fmt.Printf("new s = %v \n", s)

 fmt.Println("===== ===== ===== ===== =====")

 // c2 = [0 0 0]
 c2 := make([]int, 3)

 // 将 s 中的值依次拷贝值 c2 中
 // 此时 c2 与 s 是完全不同的内存空间(新内存空间)
 copy(c2, s)
 fmt.Printf("c2 = %v \n", c2)

}

image

0x05 相关疑问

  1. 数组可以类似切片一样通过 s[1:3] 的方式截取吗?

可以,此时新截取的变量类型为 slice。

package main

import (
 "fmt"
)

// func printArray(myArray [4]int) {
//  // 值拷贝
//  for index, value := range myArray {
//   fmt.Println("index = ", index, " , value = ", value)
//  }

//  myArray[0] = 233
// }

// func printSlice(myArray []int) {
//  // 引用传递
//  // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
//  // 动态数组是指向数组内存的指针(引用)
//  for _, value := range myArray {
//   fmt.Println("value = ", value)
//  }
//  myArray[0] = 233
// }

func main() {

 // // 固定长度数组
 // var myArray1 [10]int
 // var myArray2 [10]float32

 // myArray3 := [10]int{1, 2, 3, 4}

 // myArray4 := [4]int{11, 22, 33, 44}

 // // for i := 0; i < 10; i ++ {
 // for i := 0; i < len(myArray1); i++ {
 //  fmt.Println(myArray1[i])

 // }

 // fmt.Println("===== ===== ===== =====")

 // for j := 0; j < len(myArray2); j++ {
 //  fmt.Println(myArray2[j])
 // }

 // fmt.Println("===== ===== ===== =====")

 // for index, value := range myArray3 {
 //  fmt.Println("index= ", index, ", value = ", value)
 // }

 // // 查看数组的数据类型
 // fmt.Printf("myArray1 types = %T\n", myArray1)
 // fmt.Printf("myArray2 types = %T\n", myArray2)
 // fmt.Printf("myArray3 types = %T\n", myArray3)
 // fmt.Printf("myArray4 types = %T\n", myArray4)

 // fmt.Println("===== ===== ===== =====")

 // printArray(myArray4)

 // fmt.Println("=====")

 // for index, value := range myArray4 {
 //  fmt.Println("index = ", index, ", value = ", value)
 // }
 // var myArray5 [10]int
 // myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
 // fmt.Printf("myArray type is %T\n", myArray)

 // printSlice(myArray)

 // fmt.Println("===== ===== ===== =====")

 // // printSlice(myArray5)

 // for _, value := range myArray {
 //  fmt.Println("value = ", value)
 // }

 // // 声明 slice 的 4 种方法

 // // 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
 // slice1 := []int{1, 2, 3}
 // fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)

 // // 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
 // // 此时无法为 slice2[0] = 1 赋值,会提示越界错误
 // var slice2 []int

 // // 可以通过 make 开辟内存空间
 // slice2 = make([]int, 3)
 // slice2[0] = 233
 // fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)

 // // 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
 // var slice3 []int = make([]int, 3)
 // fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3)

 // // 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
 // slice4 := make([]int, 4)
 // fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)

 // // 判断 slice 是否为空
 // var slice5 []int
 // if slice5 == nil {
 //  fmt.Println("slice5 is nil,是一个空切片")
 // } else {
 //  fmt.Println("slice5 是有空间的")
 // }

 // // slice 切片的长度是 3,容量是 5
 // var slice6 = make([]int, 3, 5)

 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // // 向 slice6 中添加元素 1,此时 len = 4,cap = 5,[0 0 0 1]
 // slice6 = append(slice6, 1)

 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // slice6 = append(slice6, 2)
 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // // 像一个 slice 容量满了的 slice 中追加元素,Golang 会在底层开辟一定量等长的内存空间,如 原来的容量是 5,则现在的容量为 10
 // // cap = 10
 // slice6 = append(slice6, 3)
 // fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)

 // fmt.Println("===== ===== ===== ===== =====")

 // // 如果没指定 cap,则 cap = len
 // var number2 = make([]int, 3)
 // fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)

 // // cap = 6
 // number2 = append(number2, 111)
 // fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)

 // // len = 3, cap = 3
 // s := []int{111, 222, 333}

 // // 左闭右开 [0, 1)
 // s1 := s[0:1]

 // fmt.Printf("s1 = %v \n", s1)

 // // [0, 2) [111, 222]
 // s2 := s[0:2]
 // fmt.Printf("s2 = %v \n", s2)

 // // 表示截取全部元素
 // s3 := s[:]
 // fmt.Printf("s3 = %v \n", s3)

 // // 默认下限为 0, [111 222]
 // s4 := s[:2]
 // fmt.Printf("s4 = %v \n", s4)

 // // 默认上限为 len()  [222 333]

 // s5 := s[1:]
 // fmt.Printf("s5 = %v \n", s5)

 // // slice 截取后,两个 slice 仍然指向相同的内存空间
 // s1[0] = 888
 // fmt.Printf("new s = %v \n", s)

 // fmt.Println("===== ===== ===== ===== =====")

 // // c2 = [0 0 0]
 // c2 := make([]int, 3)

 // // 将 s 中的值依次拷贝值 c2 中
 // // 此时 c2 与 s 是完全不同的内存空间(新内存空间)
 // copy(c2, s)
 // fmt.Printf("c2 = %v \n", c2)

 var arr1 [5]int
 arr1 = [5]int{111, 222, 333, 444, 555}
 fmt.Printf("arr1 = %v \n", arr1)

 arr2 := arr1[2:4]
 fmt.Printf("arr2 = %v \n", arr2)

 fmt.Printf("arr1 type = %T \n", arr1)
 fmt.Printf("arr2 type = %T \n", arr2)

}

image

0x06 References

  1. https://www.bilibili.com/video/BV1gf4y1r79E?p=14&spm_id_from=pageDriver

文章来源: https://mp.weixin.qq.com/s?__biz=Mzg5NjAxNjc5OQ==&mid=2247483943&idx=1&sn=bb14e10d31e4a31a7a431ff54252216e&chksm=c006cad7f77143c11f74b79c316ae187201443795c7f62ddc57bfb31a503c20afb26c269eb5f&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh