开发者社区> 宇宙之壹粟> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Go 语言入门很简单 -- 7. Go Slices #私藏项目实操分享#

简介: Go 语言入门很简单 -- 7. Go Slices #私藏项目实操分享#
+关注继续查看

切片 slice

切片可以算是数组的一部分。 像数组一样,切片亦是可索引的并且有长度。 与数组不同,切片这个长度是可以改变的。

切片是灵活且可扩展的数据结构,可以根据需要增长和缩小。 像数组一样,切片可以索引并且有长度。 在 Go 中,数组允许您定义可以保存相同类型数据项的变量,但它不提供任何内置方法来动态增加其大小或获取子数组,但切片克服了数组的这种限制。

切片的定义

Slice 是可以调整大小的数组段,因此与数组相比,它更灵活。 像数组一样,切片是可索引的并且有长度。 切片是一种轻量级结构,它包装并表示数组的一部分。

var x []float64

切片的声明就像数组一样,但它不包含切片的大小。。 在这种情况下,x 的创建长度为 0,因此,它变得灵活且具有动态大小以适应需求。

如果你想要创建一个切片 slice ,应该使用内置的 make 函数,切片是使用 make 函数创建的。:

x := make([]float64, 3)

这将创建一个长度为 3 的类型为 float64 数组关联的切片,切片始终与某个数组关联,尽管它们永远不能长于数组,但它们可以更小。

make 函数还允许使用第三个参数:

x := make([]float64, 3, 10)

10 表示切片指向的底层数组的容量:

image.png

package main

import "fmt"

func main() {
    X := make([]float64, 3, 10)
    fmt.Printf("Slice = %v", X)
    fmt.Printf("\nLength = %d", len(X))
    fmt.Printf("\nCapacity = %d", cap(X))
}

运行代码,得到:

Slice = [0 0 0]
Length = 3
Capacity = 10

切片的声明

切片是一个可变长度的序列,它存储相似类型的元素,并且不允许在同一个切片中存储不同类型的元素。 切片中的第一个索引位置始终为 0,最后一个为(切片长度 - 1)。

另一种创建切片的方法是使用 [low : high] 表达式:

array := []float64{1, 2, 3, 4, 5}
x := array[0:5]

low 是切片的起始索引, high 是终止索引,但不包括该索引本身。

例如: array[0:5] 返回 [1,2,3,4,5]array[1:4] 得到 [2,3,4] .

为了方便,Go 语言允许省略 low , high ,甚至两个一起省略。

  • array[0:] 等同于 array[0:len(array)] .
  • array[:5] 等同于 array[0:5] .
  • array[:] 等同于 array[0:len(array)]

package main

import "fmt"

func main() {
    // Create a slice using a slice literal
    var my_slices = []int{1, 2, 3, 4, 5}
    fmt.Println("my_slices = ", my_slices)

    // Create a slice using a slice literal using short hand declaration
    my_slices2 := []int{6, 7, 8, 9, 10}
    fmt.Println("my_slices2 = ", my_slices2)
}

切片的修改

切片是引用类型,它们引用底层数组。 因此,修改切片的一个元素将修改引用数组中的相应元素,引用同一数组的其他切片也将看到这些修改。

package main

import "fmt"

func main() {

    number_English := [7]string{"One", "Two", "Three", "Four", "Five", "Six", "Seven"}

    slice1 := number_English[1:]
    slice2 := number_English[3:]

    fmt.Println("--- 修改前 ---")
    fmt.Println("Array =", number_English)
    fmt.Println("slice1 = ", slice1)
    fmt.Println("slice2 = ", slice2)

    // 修改切片
    slice1[0] = "TWO"
    slice1[2] = "FOUR"
    slice2[1] = "FIVE"

    fmt.Println("--- 修改后 ---")
    fmt.Println("Array =", number_English)
    fmt.Println("slice1 = ", slice1)
    fmt.Println("slice2 = ", slice2)
}

运行后,结果为:

--- 修改前 ---
Array = [One Two Three Four Five Six Seven]
slice1 =  [Two Three Four Five Six Seven]
slice2 =  [Four Five Six Seven]
--- 修改后 ---
Array = [One TWO Three FOUR FIVE Six Seven]
slice1 =  [TWO Three FOUR FIVE Six Seven]
slice2 =  [FOUR FIVE Six Seven]

空值切片

Nil slice 中不包含任何元素。 所以,这个切片的容量和长度都是 0。Nil 切片不包含数组引用。 让我们看看下面的例子:

package main

import "fmt"

func main() {

    var nil_slices []string
    fmt.Printf("Length of slice: %d\n", len(nil_slices))
    fmt.Printf("Capacity: %d\n", cap(nil_slices))
}

运行结果为:

Length of slice: 0
Capacity: 0

切片是否为空

使用 == 来检查切片是否为空,如:

package main

import "fmt"

func main() {

    x1 := []int{1, 2, 3, 4, 5, 6}
    var x2 []int

    fmt.Println(x1 == nil)
    fmt.Println(x2 == nil)
}

将会得到:

false
true

多维切片

多维切片就像多维数组一样,只是切片不包含大小。 让我们看看下面的例子:

package main

import "fmt"

func main() {

    x1 := [][]int{
        {10, 20},
        {20, 30},
        {30, 40},
        {40, 100},
    }

    x2 := [][]string{
        {"1", "小王"},
        {"2", "小李"},
        {"3", "小张"},
    }

    fmt.Println("Slice 1: ", x1)
    fmt.Println("Slice 2: ", x2)
    fmt.Println("Length of slice 1: ", len(x1))
    fmt.Println("Length of slice 2: ", len(x2))
}

结果:

Slice 1:  [[10 20] [20 30] [30 40] [40 100]]
Slice 2:  [[1 小王] [2 小李] [3 小张]]
Length of slice 1:  4
Length of slice 2:  3

切片操作

排序

在 Go 语言中,您可以对切片中存在的元素进行排序。 Go 标准库提供了 sort 包,其中包含不同类型的排序方法。

package main

import (
    "fmt"
    "sort"
)

func main() {

    slice1 := []string{"India", "Japan", "China", "Ecuador", "New Zealand", "USA", "UK"}
    slice2 := []int{6, 7, 1, 9, 40, 1100, 122, 33, 414}

    fmt.Println("Slice 1: ", slice1)
    fmt.Println("Slice 2: ", slice2)

    sort.Strings(slice1)
    sort.Ints(slice2)
    fmt.Println("--- After sort ---")
    fmt.Println("Slice 1: ", slice1)
    fmt.Println("Slice 2: ", slice2)
}

结果为:

Slice 1:  [India Japan China Ecuador New Zealand USA UK]
Slice 2:  [6 7 1 9 40 1100 122 33 414]
--- After sort ---
Slice 1:  [China Ecuador India Japan New Zealand UK USA]
Slice 2:  [1 6 7 9 33 40 122 414 1100]

遍历

您可以通过使用 for 循环或 for range 循环来遍历切片。

package main

import (
    "fmt"
)

func main() {

    slice1 := []string{"India", "Japan", "China", "Ecuador", "New Zealand", "USA", "UK"}

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

    for index, element := range slice1 {
        fmt.Printf("Index = %d, Element = %s\n", index, element)
    }
}

结果为:

India
Japan
China
Ecuador
New Zealand
USA
UK
Index = 0, Element = India
Index = 1, Element = Japan
Index = 2, Element = China
Index = 3, Element = Ecuador
Index = 4, Element = New Zealand
Index = 5, Element = USA
Index = 6, Element = UK

添加

使用 append 方法可以往切片里添加另一个 切片,append 通过获取现有切片(第一个参数)并将以下所有参数附加到它来创建一个新切片:

package main

import (
    "fmt"
)

func main() {

    slice1 := []string{"India", "Japan", "China", "Ecuador", "New Zealand", "USA", "UK"}
    slice2 := append(slice1, "Russia", "France", "Germany", "Belgium")
    fmt.Println(slice1)
    fmt.Println(slice2)
}

结果为:

[India Japan China Ecuador New Zealand USA UK]
[India Japan China Ecuador New Zealand USA UK Russia France Germany Belgium]

复制

copy 可以将一个切片的元素复制到另一个元素中:

package main

import (
    "fmt"
)

func main() {

    slice1 := []string{"India", "Japan", "China", "Ecuador", "New Zealand", "USA", "UK"}
    slice2 := append(slice1, "Russia", "France", "Germany", "Belgium")
    fmt.Println(slice1)
    fmt.Println(slice2)

    slice3 := make([]string, 12)
    copy(slice3, slice2)
    fmt.Println(slice3)
}

结果为:

[India Japan China Ecuador New Zealand USA UK]
[India Japan China Ecuador New Zealand USA UK Russia France Germany Belgium]
[India Japan China Ecuador New Zealand USA UK Russia France Germany Belgium ]

总结

在 Go 中,切片是数组的一部分,可以调整大小,比数组更灵活。 像数组一样,切片是可索引的并且有长度。

切片是一种轻量级结构,它包装并表示数组的一部分。 切片由三部分组成——指针、长度和容量。

在 Go 语言中,切片就像数组一样声明,但它不包含切片的大小。 因此,它在尺寸上变得灵活和动态以适应要求。

为了从数组创建切片,我们指定了两个索引,用冒号分隔的下限和上限。 low 的默认值为 0,high 是切片的长度。 切片表达式中的低和高索引是可选的。

在 Go 中,您可以使用 Go 库提供的 make() 函数创建切片。 这个函数需要三个参数——类型、长度和容量。 这里,容量值是可选的。 它分配一个大小等于给定容量的底层数组,并返回一个引用底层数组的切片。

切片是 Go 语言中的引用类型,它们引用底层数组。 因此,修改切片的元素将修改引用数组中的相应元素,引用同一数组的其他切片也将看到这些修改。

在 Go 中,一个 nil 切片中不包含任何元素。 因此,该切片的容量和长度均为 0,并且 nil 切片不包含数组引用。 此外,您可以在 slice 中使用 == 运算符来检查给定的 slice 是否为零。

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

您可以使用 for 循环或 for 循环中的 range 遍历切片。 通过在 for 循环中使用范围,您还可以获得索引和元素值。

在 Go 中,您可以对切片中的元素进行排序。 Go 标准库提供了 sort 包,其中包含不同类型的排序方法,用于对切片进行排序。还可以通过 append 和 copy 往一个切片中添加元素。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
go语言入门
go 语言下载地址: http://code.google.com/p/go/downloads/list 下载 轻量开发工具 http://code.google.com/p/liteide/   我为什么喜欢Go语言 使用CGO封装Windows API 用Go写Windows桌面...
846 0
Go语言入门分享
Go语言出自Ken Thompson、Rob Pike和Robert Griesemer之手,起源于2007年,并在2009年正式对外发布。Go的主要目标是“兼具Python等动态语言的开发速度和C/C++等编译型语言的性能与安全性”,旨在不损失应用程序性能的情况下降低代码的复杂性,具有“部署简单、并发性好、语言设计良好、执行性能好”等优势。
0 0
Go 语言入门很简单 -- 16. Go 并发互斥锁 #私藏项目实操分享#
Go 语言入门很简单 -- 16. Go 并发互斥锁 #私藏项目实操分享#
0 0
Go 语言入门很简单--技巧和窍门(Tips and Tricks)
Go 语言入门很简单--技巧和窍门(Tips and Tricks)
0 0
go语言简单入门
go语言简单入门
0 0
Go 语言入门很简单:基准测试
Go 测试包包含一个基准测试工具,用于检查我们的 Go 代码的性能。 在本文中,我们将使用基准工具来逐步提高一段代码的性能。 然后,我们将讨论先进的基准测试技术,以确保我们测量的是正确的东西。
0 0
Go 语言入门很简单:时间包
时间和日期对于任何编程语言来说都是一个非常重要的包。 GO 语言 提供了 time 包来测量和显示时间。既可以根据所选时区获取当前时间,又可以使用 time 包添加当前时区的持续时间等。
0 0
Go 语言入门很简单:正则表达式(上)
在计算中,我们经常需要将特定模式的字符或字符子集匹配为另一个字符串中的字符串。此技术用于使用特别的语法来搜索给定字符串中的特定字符集。比如邮件、手机号、身份证号等等。 如果搜索到的模式匹配,或者在目标字符串中找到给定的子集,则搜索被称为成功;否则被认为是不成功的。 那么此时该用到正则表达式了。
0 0
Go 语言入门很简单:Go 计时器
一般来说,很多时候我们面临这样一种情况,即我们需要运行时间记录器,它不断向我们显示当前时间或在给定的时间间隔内保持执行一定的代码和平,在这种情况下,我们应该使用 Ticker,使用这个我们需要使用 go 语言的 time 包,我们有一个名为 NewTicker() 的方法,它允许我们停止和启动时间代码,我们需要通过传递 chan 和 bool 作为将使用的参数来创建一个代码通道检查它是否打开,如果通道打开意味着计时器将继续。
0 0
Go 语言入门很简单:上下文(下)
Golang 的 Context 应用开发常用的并发控制工具,用于在程序中的 API 层或进程之间共享请求范围的数据、取消信号以及超时或截止日期。
0 0
+关注
宇宙之壹粟
目前就职于外企软件工程师;InfoQ签约作者;51CTO首席体验官;后端开拓者;头发比想法多的研究僧; 混迹于江湖,江湖却没有我的影子 热爱技术,专注于后端全栈,轻易不换岗 拒绝内卷,工作于软件工程师,弹性不加班 热衷分享,执着于阅读写作,佛系不水文
文章
问答
文章排行榜
最热
最新
相关电子书
更多
基于 OpenResty 和 Node.js 的个推微服务实践
立即下载
Go语言路上踩过的坑
立即下载
Go 构建日请求千亿级微服务的最佳实践
立即下载