0


golang 切片详解

Go 中的切片是一种灵活且高效的表示数组的方式,并且由于其动态大小和附加功能,它们经常用来代替数组。切片是对数组的一部分的引用。它是一种数据结构,通过指定起始索引和部分长度来描述数组的一部分。这允许您像使用独立数组一样使用数组的一部分。Go语言中切片比数组更强大、更灵活、更方便,是一种轻量级的数据结构。切片是一个变长序列,用于存储相似类型的元素,不允许在同一个切片中存储不同类型的元素。它就像一个具有索引值和长度的数组,但是切片的大小是调整大小的,它们不像数组那样是固定大小的。在内部,切片和数组是相互连接的,切片是对底层数组的引用。切片中允许存储重复元素。

***切片中的第一个索引位置始终为 0,最后一个索引位置将为 (切片长度 – 1)***。

如何在 Go 中创建切片的示例:

package main

import"fmt"funcmain(){
    array :=[5]int{1,2,3,4,5}
    slice := array[1:4]

    fmt.Println("Array: ", array)
    fmt.Println("Slice: ", slice)}

Output:

Array: [1 2 3 4 5]
Slice: [2 3 4] 

在此示例中,创建的数组包含 5 个元素,并且通过指定起始索引 1 和长度 4 创建切片。切片现在包含原始数组中的元素 2、3 和 4。

切片是动态的,这意味着它们的大小可以随着您添加或删除元素而改变。Go 提供了几个内置函数允许您修改切片,例如追加、复制和删除。

如何在 Go 中向切片添加元素:

package main

import"fmt"funcmain(){
    slice :=[]int{1,2,3}
    slice =append(slice,4,5,6)

    fmt.Println("Slice: ", slice)}

Output:

Slice: [1 2 3 4 5 6] 

本例中,函数append用于将元素4、5、6添加到切片slice中。结果是一个包含元素 1、2、3、4、5、6 的新切片。

Go 中的切片是一种强大且灵活的数据结构,可用于表示数组。它们提供了一种更动态、更高效的数组处理方式,并且广泛应用于 Go 程序中。

切片声明

切片的声明方式与数组类似,但它不包含切片的大小。所以它可以根据需要增长或缩小。

Syntax:

[]T
or 
[]T{}
or 
[]T{value1, value2, value3, ...value n}

例如:

var my_slice[]int 

切片的组成部分

切片包含三个组件:

指针:指针用于指向可通过切片访问的数组的第一个元素。这里,所指向的元素不一定是数组的第一个元素。
长度: 长度是数组中存在的元素总数。
容量: 容量表示可以扩展的最大大小。

示例:

// Golang program to illustrate// the working of the slice componentspackage main

import"fmt"funcmain(){// Creating an array
    arr :=[7]string{"This","is","the","tutorial","of","Go","language"}// Display array
    fmt.Println("Array:", arr)// Creating a slice
    myslice := arr[1:6]// Display slice
    fmt.Println("Slice:", myslice)// Display length of the slice
    fmt.Printf("Length of the slice: %d",len(myslice))// Display the capacity of the slice
    fmt.Printf("\nCapacity of the slice: %d",cap(myslice))}

Output:

Array: [This is the tutorial of Go language]
Slice: [is the tutorial of Go]
Length of the slice: 5
Capacity of the slice: 6

**说明:*在上面的示例中,我们从给定数组创建一个切片。这里切片的指针指向索引 1,因为切片的下界设置为 1,因此它从索引 1 开始访问元素。切片的长度为 5,这意味着切片中存在的元素总数为5和切片6的容量意味着它最多可以存储6个元素。

在这里插入图片描述

如何创建和初始化Slice?

在Go语言中,切片可以通过以下方式创建和初始化:

使用切片文字:您可以使用切片文字创建切片。切片文字的创建就像数组文字一样,但有一点不同,不允许在方括号 [] 中指定切片的大小。如下例所示,该表达式的右侧是切片文字。

var my_slice_1 =[]string{"极客","for","极客"}

注意: 当您使用字符串文字创建切片时,它首先创建一个数组,然后返回对其的切片引用。

示例:

// Golang program to illustrate how// to create a slice using a slice// literalpackage main

import"fmt"funcmain(){// Creating a slice// using the var keywordvar my_slice_1 =[]string{"Geeks","for","Geeks"}

    fmt.Println("My Slice 1:", my_slice_1)// Creating a slice//using shorthand declaration
    my_slice_2 :=[]int{12,45,67,56,43,34,45}
    fmt.Println("My Slice 2:", my_slice_2)}

Output:

My Slice 1: [Geeks for Geeks]
My Slice 2: [12 45 67 56 43 34 45]

使用数组: 我们已经知道切片是数组的引用,因此您可以从给定数组创建切片。要从给定数组创建切片,首先需要指定下限和上限,这意味着切片可以从数组中从下限到上限获取元素。它不包括上面的上限元素。如下例所示:

Syntax:

array_name[low:high]

此语法将返回一个新切片。

注意: 下界的默认值为 0,上限的默认值为给定数组中存在的元素总数。

示例:

// Golang program to illustrate how to// create slices from the arraypackage main

import"fmt"funcmain(){// Creating an array
    arr :=[4]string{"Geeks","for","Geeks","GFG"}// Creating slices from the given arrayvar my_slice_1 = arr[1:2]
    my_slice_2 := arr[0:]
    my_slice_3 := arr[:2]
    my_slice_4 := arr[:]// Display the result
    fmt.Println("My Array: ", arr)
    fmt.Println("My Slice 1: ", my_slice_1)
    fmt.Println("My Slice 2: ", my_slice_2)
    fmt.Println("My Slice 3: ", my_slice_3)
    fmt.Println("My Slice 4: ", my_slice_4)}

Output:

My Array:  [Geeks for Geeks GFG]
My Slice 1:  [for]
My Slice 2:  [Geeks for Geeks GFG]
My Slice 3:  [Geeks for]
My Slice 4:  [Geeks for Geeks GFG]

使用已经存在的切片: 也可以从给定的切片创建切片。要从给定切片创建切片,首先需要指定下限和上限,这意味着切片可以从给定切片中从下限到上限获取元素。它不包括上面的上限元素。如下例所示:
语法:

slice_name[low:high]

此语法将返回一个新切片。

注意: 下界的默认值为 0,上限的默认值为给定切片中存在的元素总数。

示例:

// Golang program to illustrate how to// create slices from the slicepackage main

import"fmt"funcmain(){// Creating s slice
    oRignAl_slice :=[]int{90,60,40,50,34,49,30}// Creating slices from the given slicevar my_slice_1 = oRignAl_slice[1:5]
    my_slice_2 := oRignAl_slice[0:]
    my_slice_3 := oRignAl_slice[:6]
    my_slice_4 := oRignAl_slice[:]
    my_slice_5 := my_slice_3[2:4]// Display the result
    fmt.Println("Original Slice:", oRignAl_slice)
    fmt.Println("New Slice 1:", my_slice_1)
    fmt.Println("New Slice 2:", my_slice_2)
    fmt.Println("New Slice 3:", my_slice_3)
    fmt.Println("New Slice 4:", my_slice_4)
    fmt.Println("New Slice 5:", my_slice_5)}

Output:

Original Slice: [90 60 40 50 34 49 30]
New Slice 1: [60 40 50 34]
New Slice 2: [90 60 40 50 34 49 30]
New Slice 3: [90 60 40 50 34 49]
New Slice 4: [90 60 40 50 34 49 30]
New Slice 5: [40 50]

使用 make() 函数: 您还可以使用go 库提供的make() 函数创建切片。该函数采用三个参数,即类型、长度和容量。这里,容量值是可选的。它分配一个大小等于给定容量的底层数组,并返回一个引用底层数组的切片。通常,make()函数用于创建一个空切片。这里,空切片是那些包含空数组引用的切片。

语法:

func make([]T, len, cap) []T

示例:

// Go program to illustrate how to create slices// Using make functionpackage main

import"fmt"funcmain(){// Creating an array of size 7// and slice this array till 4// and return the reference of the slice// Using make functionvar my_slice_1 =make([]int,4,7)
    fmt.Printf("Slice 1 = %v, \nlength = %d, \ncapacity = %d\n",
                my_slice_1,len(my_slice_1),cap(my_slice_1))// Creating another array of size 7// and return the reference of the slice// Using make functionvar my_slice_2 =make([]int,7)
    fmt.Printf("Slice 2 = %v, \nlength = %d, \ncapacity = %d\n",
                my_slice_2,len(my_slice_2),cap(my_slice_2))}

Output:

Slice 1 = [0 0 0 0], 
length = 4, 
capacity = 7
Slice 2 = [0 0 0 0 0 0 0], 
length = 7, 
capacity = 7

如何迭代切片?

您可以使用以下方式迭代切片:

使用 for 循环:这是迭代切片的最简单方法,如下例所示:
示例:

// Golang program to illustrate the// iterating over a slice using// for looppackage main

import"fmt"funcmain(){// Creating a slice
    myslice :=[]string{"This","is","the","tutorial","of","Go","language"}// Iterate using for loopfor e :=0; e <len(myslice); e++{
        fmt.Println(myslice[e])}}

Output:

This
is
the
tutorial
of
Go
language

在 for 循环中使用 range:允许在 for 循环中使用 range 来迭代切片。在 for 循环中使用 range,您可以获取索引和元素值,如示例所示:

示例:

// Golang program to illustrate the iterating// over a slice using range in for looppackage main

import"fmt"funcmain(){// Creating a slice
    myslice :=[]string{"This","is","the","tutorial","of","Go","language"}// Iterate slice// using range in for loopfor index, ele :=range myslice {
        fmt.Printf("Index = %d and element = %s\n", index+3, ele)}}

Output:

Index = 3 and element = This
Index = 4 and element = is
Index = 5 and element = the
Index = 6 and element = tutorial
Index = 7 and element = of
Index = 8 and element = Go
Index = 9 and element = language

在 for 循环中使用空白标识符:在 range for 循环中,如果您不想获取元素的索引值,则可以使用空格(_)代替索引变量,如下例所示:
示例:

// Golang program to illustrate the iterating over// a slice using range in for loop without an indexpackage main

import"fmt"funcmain(){// Creating a slice
    myslice :=[]string{"This","is","the","tutorial","of","Go","language"}// Iterate slice// using range in for loop// without indexfor_, ele :=range myslice {
        fmt.Printf("Element = %s\n", ele)}}

Output:

Element = This
Element = is
Element = the
Element = tutorial
Element = of
Element = Go
Element = language

关于 Slice 的要点

零值切片:在Go语言中,您可以创建一个不包含任何元素的nil切片。因此该切片的容量和长度为 0。 Nil 切片不包含数组引用,如下例所示:

示例:

// Go program to illustrate a zero value slicepackage main

import"fmt"funcmain(){// Creating a zero value slicevar myslice []string
    fmt.Printf("Length = %d\n",len(myslice))
    fmt.Printf("Capacity = %d ",cap(myslice))}

Output:

Length = 0
Capacity = 0

修改切片:我们已经知道切片是一种引用类型,它可以引用底层数组。因此,如果我们更改切片中的某些元素,那么更改也应该发生在引用的数组中。或者换句话说,如果您在切片中进行了任何更改,那么它也会反映在数组中,如下例所示:

示例:

// Golang program to illustrate// how to modify the slicepackage main

import"fmt"funcmain(){// Creating a zero value slice
    arr :=[6]int{55,66,77,88,99,22}
    slc := arr[0:4]// Before modifying

    fmt.Println("Original_Array: ", arr)
    fmt.Println("Original_Slice: ", slc)// After modification
    slc[0]=100
    slc[1]=1000
    slc[2]=1000

    fmt.Println("\nNew_Array: ", arr)
    fmt.Println("New_Slice: ", slc)}

Output:

Original_Array:  [55 66 77 88 99 22]
Original_Slice:  [55 66 77 88]

New_Array:  [100 1000 1000 88 99 22]
New_Slice:  [100 1000 1000 88]

Slice 的比较:在 Slice 中,只能使用运算符来检查给定的 slice 是否为空。如果您尝试借助运算符比较两个切片,则会出现错误,如下例所示:

示例:

// Golang program to check if// the slice is nil or notpackage main

import"fmt"funcmain(){// creating slices
    s1 :=[]int{12,34,56}var s2 []int// If you try to run this commented// code compiler will give an error/*s3:= []int{23, 45, 66}
    fmt.Println(s1==s3)
    */// Checking if the given slice is nil or not
    fmt.Println(s1 ==nil)
    fmt.Println(s2 ==nil)}

Output:

false
true

注意:如果要比较两个切片,请使用 range for 循环来匹配每个元素,或者可以使用DeepEqual函数。

多维切片:多维切片就像多维数组一样,只是切片不包含大小。

示例:

// Go program to illustrate the multi-dimensional slicepackage main

import"fmt"funcmain(){// Creating multi-dimensional slice
    s1 :=[][]int{{12,34},{56,47},{29,40},{46,78},}// Accessing multi-dimensional slice
    fmt.Println("Slice 1 : ", s1)// Creating multi-dimensional slice
    s2 :=[][]string{[]string{"Geeks","for"},[]string{"Geeks","GFG"},[]string{"gfg","geek"},}// Accessing multi-dimensional slice
    fmt.Println("Slice 2 : ", s2)}

Output:

Slice 1 :  [[12 34] [56 47] [29 40] [46 78]]
Slice 2 :  [[Geeks for] [Geeks GFG] [gfg geek]]

切片的排序:在Go语言中,您可以对切片中存在的元素进行排序。Go语言的标准库提供了sort包,其中包含不同类型的排序方法,用于对int、float64和strings切片进行排序。这些函数始终按升序对切片中可用的元素进行排序。

示例:

// Go program to illustrate how to sort// the elements present in the slicepackage main

import("fmt""sort")funcmain(){// Creating Slice
    slc1 :=[]string{"Python","Java","C#","Go","Ruby"}
    slc2 :=[]int{45,67,23,90,33,21,56,78,89}

    fmt.Println("Before sorting:")
    fmt.Println("Slice 1: ", slc1)
    fmt.Println("Slice 2: ", slc2)// Performing sort operation on the// slice using sort function
    sort.Strings(slc1)
    sort.Ints(slc2)

    fmt.Println("\nAfter sorting:")
    fmt.Println("Slice 1: ", slc1)
    fmt.Println("Slice 2: ", slc2)}

Output:

Before sorting:
Slice 1:  [Python Java C# Go Ruby]
Slice 2:  [45 67 23 90 33 21 56 78 89]

After sorting:
Slice 1:  [C# Go Java Python Ruby]
Slice 2:  [21 23 33 45 56 67 78 89 90]

本文转载自: https://blog.csdn.net/m0_37698352/article/details/132047659
版权归原作者 OneGopher 所有, 如有侵权,请联系我们删除。

“golang 切片详解”的评论:

还没有评论