Go语言:切片(Slice)的一些有趣特性

  1. 切片类似数组的引用。更改底层数组中的元素会修改切片的元素。更改切片的元素同样会修改其底层数组中的元素,和它共享底层数组的切片都会观测到这些修改。
点击查看代码
package main

import "fmt"

func main() {
	names := [4]string{
		"John",
		"Paul",
		"George",
		"Ringo",
	}
	fmt.Println(names)  // [John Paul George Ringo]

	a := names[0:2]
	b := names[1:3]
	fmt.Println(a, b)  // [John Paul] [Paul George]

	names[1] = "gyt"
	fmt.Println(a, b)  // [John gyt] [gyt George]
	fmt.Println(names)  // [John gyt George Ringo]
}
  1. 切片的长度和容量。切片的长度就是它所包含的元素个数。切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。当切片的左边界设置一个大于0的数时,会改变切片的容量,其他情况容量不会改变。
点击查看代码
package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)  // len=6 cap=6 [2 3 5 7 11 13]

	s = s[:0]
	printSlice(s)  // len=0 cap=6 []

    s = s[:4]
	printSlice(s)  // len=4 cap=6 [2 3 5 7]

	s = s[1:4]
	printSlice(s)  // len=3 cap=5 [3 5 7]

	s = s[2:]
	printSlice(s)  // len=1 cap=3 [7]

}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
  1. 对切片进行切片。第二次切片默认会在第一次切片的结果上进行,但如果第二次切片的右边界大于第一次切片的len,第二次切片会对其底层数组再进行切片,换句话说,是对容量而不是长度再进行切片。正如下面代码所示,“s[:]”此时不等于“s[:6]”。
点击查看代码
package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)  // len=6 cap=6 [2 3 5 7 11 13]

	s = s[:0]
	printSlice(s)  // len=0 cap=6 []

	printSlice(s[:])  // len=0 cap=6 []
	printSlice(s[:6])  // len=6 cap=6 [2 3 5 7 11 13]
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
  1. append特性。如果在切片的中间进行append的话,它会覆盖一个值,并不改变切片的容量。如果在末尾进行append的话,它就会分配一个更大的数组。 返回的切片会指向这个新分配的数组。
点击查看代码
package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)  // len=6 cap=6 [2 3 5 7 11 13]

	s = s[:4]
	printSlice(s)  // len=4 cap=6 [2 3 5 7]

	s = append(s, 0)
	printSlice(s)  // len=5 cap=6 [2 3 5 7 0]
	printSlice(s[:6])  // len=6 cap=6 [2 3 5 7 0 13]

	s = append(s[:6], 0)
	printSlice(s)  // len=7 cap=12 [2 3 5 7 0 13 0]
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
  1. copy特性。copy是按照切片的len进行粘贴的,不足或者超过len的进行补0。
点击查看代码
package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)  // len=6 cap=6 [2 3 5 7 11 13]

	s2 := make([]int, 5, 6)
	copy(s2, s)
	printSlice(s2)  // len=5 cap=6 [2 3 5 7 11]
	printSlice(s2[:6])  // len=6 cap=6 [2 3 5 7 11 0]

	s3 := make([]int, 7, 7)
	copy(s3, s)
	printSlice(s3)  // len=7 cap=7 [2 3 5 7 11 13 0]
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
posted @ 2024-11-07 10:57  ZeroZeroSeven  阅读(18)  评论(0编辑  收藏  举报