自学内容网 自学内容网

Go基础知识:切片

数组

Go 数组的大小是固定的,其长度是其类型的一部分([4]int并且[5]int是不同的、不兼容的类型)

var a [10]int

b := [2]string{"Penn", "Teller"}
b := [...]string{"Penn", "Teller"}

package main

import "fmt"

func main() {
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)

primes := [6]int{2, 3, 5, 7, 11, 13}
fmt.Println(primes)
}

Go的数组表示值,数组变量表示整个数组;它不是指向第一个数组元素的指针(在 C 中是这种情况)。这意味着当您分配或传递数组值时,您将复制其内容。(为了避免复制,您可以将指针传递给数组,但那是指向数组的指针,而不是数组。)


package main

import "fmt"

// 函数接收数组指针作为参数。
// 如果不用指针,接收到的将是arr的副本,在函数内部修改不会影响到原数组。
func modifyArrayPointer(arr *[5]int) {
arr[0] = 100                                    // 修改数组的第一个元素
fmt.Println("Inside modifyArrayPointer:", *arr) // 打印修改后的数组
}

func main() {
arr := [5]int{1, 2, 3, 4, 5}
fmt.Println("修改前:", arr)

modifyArrayPointer(&arr) // 传递数组的指针

fmt.Println("修改后:", arr) // 原数组被改变
}


切片

切片类型是基于Go数组类型之上的抽象,提供了更强大的功能和便利性。
数组大小固定,而切片则为数组元素提供了动态大小、灵活的视角。在实践中,切片比数组更常用。
切片是数组段的描述符。由指向数组的指针、段的长度及其容量(段的最大长度)组成。

[]T 表示一个元素类型为T的切片。

切片通过两个下标界定,左闭右开

a[low : high]

如下表示,包含下标从1到3的元素

a[1:4]

package main

import "fmt"

func main() {
primes := [6]int{2, 3, 5, 7, 11, 13}

var s []int = primes[1:4]
fmt.Println(s)
}

在这里插入图片描述
s := make([]byte, 5) 结构如下

在这里插入图片描述

s = s[2:4]
在这里插入图片描述

切片类似数组引用

切片就像数组的引用 切片并不存储任何数据,它只是描述了底层数组中的一段。

更改切片的元素会修改其底层数组中对应的元素。
它共享底层数组的切片都会观测到这些修改。

使用字面量或make创建切片时,会创建一个新的底层数组。
使用数组或切片重新切片时,不会创建新的数组,而是引用已有的底层数组。

package main

import "fmt"

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

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

b[0] = "XXX"
fmt.Println(a, b)
fmt.Println(names)
}

切片字面量(Slice literals)

切片字面量类似于没有长度的数组字面量。

// 这是一个数组字面量:
[3]bool{true, true, false}

//下面这样则会创建一个和上面相同的数组,然后再构建一个引用了它的切片:
[]bool{true, true, false}

切片默认行为

在进行切片时,你可以利用它的默认行为来忽略上下界。
切片下界的默认值为 0,上界则是该切片的长度。
对于数组

var a [10]int

来说,以下切片表达式和它是等价的

a[0:10]
a[:10]
a[0:]
a[:]

给定数组创建切片

x := [3]string{"Лайка", "Белка", "Стрелка"}
s := x[:] // a slice referencing the storage of x

切片长度与容量

切片的长度就是它所包含的元素个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。

  • len(s) 切片长度
  • cap(s) 切片容量

切片的零值是nil。nil切片的长度和容量为0,且没有底层数组。

使用make创建切片

a := make([]int, 5)  // len(a)=5

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:]      // len(b)=4, cap(b)=4

使用append向切片追加元素

func append(s []T, vs ...T) []T

append 的第一个参数 s 是一个元素类型为 T 的切片,其余类型为 T 的值将会追加到该切片的末尾。
append 的结果是一个包含原切片所有元素加上新添加元素的切片。

当 s 的底层数组太小,不足以容纳所有给定的值时,它就会分配一个更大的数组。 返回的切片会指向这个新分配的数组。

package main

import "fmt"

func main() {
var s []int
printSlice(s)

// 可在空切片上追加
s = append(s, 0)
printSlice(s)

// 这个切片会按需增长
s = append(s, 1)
printSlice(s)

// 可以一次性添加多个元素
s = append(s, 2, 3, 4)
printSlice(s)
}

func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

使用range遍历切片

当使用 for 循环遍历切片时,每次迭代都会返回两个值。 第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。

package main

import "fmt"

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}

来源

https://tour.go-zh.org/
https://go.dev/tour/welcome/1
https://go.dev/blog/slices-intro


原文地址:https://blog.csdn.net/zhangj1125/article/details/142886156

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!