Golang Slice切片

1. 切片的定义和初始化

  • 切片是基于数组类型的封装,非常灵活,可以自动扩容
  • 切片是真正意义上的动态数组,而且是一个引用类型,切片指向一个底层数组

定义切片

var 切片名[] 切片类型

创建切片方式

package main

import "fmt"

func main() {
    // 1. 声明切片
    var s1 []int
    if s1 == nil { // 只声明没有初始化,所以是nil
        fmt.Println("为空")
    } else {
        fmt.Println("不为空")
    }

    // 2. := 自动推导
    s2 := []int{}

    // 3. make(切片类型, 长度, 容量)
    // 容量是可选的
    var s3 []int = make([]int, 0)

    fmt.Println(s1, s2, s3)

    // 4. 初始化赋值
    var s4 []int = make([]int, 0, 0)
    fmt.Println(s4)

    s5 := []int{1,2,3}
    fmt.Println(s5)

    // 5. 从数组切片
    arr := [5]int{1,2,3,4,5}
    var s6 []int
    s6 = arr[1:4]
    fmt.Println(s6)
}

2. 切片操作

操作 含义
s[n] 切片 s 中索引位置为 n 的项
s[:] 从切片 s 的索引位置 0 到 len(s)-1 处所获得的切片
s[low:] 从切片 s 的索引位置 low 到 len(s)-1 处所获得的切片
s[:high] 从切片 s 的索引位置 0 到 high 处所获得的切片,len=high
s[low:high] 从切片 s 的索引位置 low 到 high 处所获得的切片,len=high-low
s[low: high:max] 从切片 s 的索引位置 low 到 high 处所获得的切片,len=high-low, cap=max-low
len(s) 切片 s 的长度,总是<=cap()
cap(s) 切片 s 的容量,总是>=len(s)
package main

import "fmt"

func op01() {
    // 定义数组
    array := [...]int{1, 2, 3, 4, 5, 6, 7, 9, 0}

    // 切片
    fmt.Println(array[:])
    fmt.Println(array[1:5])
    fmt.Println(array[:6])
    fmt.Println(array[2:])
    fmt.Println(array[2])
}

func op02() {
    s1 := make([]int, 3, 5)
    fmt.Printf("s1: %v, len: %d, cap: %d", s1, len(s1), cap(s1))
}

func op03() {
    // 初始化一个数组
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8}

    s1 := arr[2:5]
    fmt.Println(s1)

    // 可以向后扩展,默认是不扩展,不可以向前扩展
    s2 := s1[2:7]
    fmt.Println(s2)
}

func main() {
    op01()
    op02()
    op03()
}

3. append()函数

向 slice 尾部添加数据,返回新的 slice 对象

package main

import "fmt"

func main() {
    // 空切片
    var s001 []int

    s001 = append(s001, 1)
    s001 = append(s001, 3)
    s001 = append(s001, 6)
    fmt.Println(s001)

    // 初始化内存的切片
    s002 := make([]int, 5)
    s002 = append(s002, 5, 8, 9)
    fmt.Println(s002)

    // 初始化默认值的切片
    s003 := []int{1, 3, 6}
    s003 = append(s003, 4, 99, 2)
    fmt.Println(s003)
}
package main

import "fmt"

func main() {
    // 初始化一个数组
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8}

    // 初始化一个从数组切片的slice
    s1 := arr[2:]
    fmt.Println(arr)
    fmt.Println(s1)

    // 修改s1切片的值
    // view(视图)操作,会修改原数组的值
    s1[0] = 100
    fmt.Println(s1)
    fmt.Println(arr)
}

// 输出结果
// [0 1 2 3 4 5 6 7 8]
// [2 3 4 5 6 7 8]
// [100 3 4 5 6 7 8]
// [0 1 100 3 4 5 6 7 8]
package main

import "fmt"

func main() {
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    s1 := arr[2:6]
    fmt.Println(s1)
    s2 := s1[3:5]
    fmt.Println(s2)

    // 映射到底层是覆盖操作
    s3 := append(s2, 10)
    fmt.Println(s3)
    fmt.Println(arr)
    fmt.Println()

    // 底层去自动扩容, 此时打印的是原数组
    s4 := append(s3, 11)
    fmt.Println(s4)
    fmt.Println(arr)

    s5 := append(s4, 12)
    fmt.Println(s5)
    fmt.Println(arr)
}
package main

import "fmt"

func main() {
    var a []int = []int{1, 2, 3}
    var b []int = []int{4, 5, 6}

    a = append(a, 7, 8)
    fmt.Println(a)

    // append无法直接添加一个切片,需要使用...将切片打散
    a = append(a, b...)
    fmt.Println(a)
}

4. copy()函数

在两个 slice 间复制数据,两个 slice 可指向同一底层数组

package main

import "fmt"

func main() {
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
    s1 := arr[8:] // [8 9 10 11 12 13 14]
    s2 := arr[:5] // [0 1 2 3 4]
    fmt.Println(s1, s2)

    // 从左侧开始覆盖
    copy(s1, s2)
    fmt.Println(s1, s2) // [0 1 2 3 4 13 14] [0 1 2 3 4]
    fmt.Println(arr)    // [0 1 2 3 4 5 6 7 0 1 2 3 4 13 14]
}

5. 切片扩容机制

用 make()创建切片,可以指定容量,当容量存储到上限,底层会自动扩容

package main

import "fmt"

func main() {
    var a []int = make([]int, 5, 10)
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

    a[0] = 10
    a[1] = 20
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

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

    for i := 0; i <= 8; i++ {
        a = append(a, i)
        fmt.Printf("for a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

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

切片再切片

package main

import "fmt"

func main() {
    a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
    b := a[1:3]
    fmt.Printf("b=%v, len=%d, cap=%d\n", b, len(b), cap(b))

    // 切片再切片
    b = b[:cap(b)]
    fmt.Printf("b=%v, len=%d, cap=%d\n", b, len(b), cap(b))
}

空切片的扩容机制

package main

import "fmt"

func main() {
    var a []int
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

    a = append(a, 10)
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
    a = append(a, 20)
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
    a = append(a, 30)
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
    a = append(a, 40)
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
    a = append(a, 50)
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
    a = append(a, 60)
    fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
}

原文地址:https://www.cnblogs.com/zhichaoma/p/12510015.html

时间: 2024-09-27 10:17:56

Golang Slice切片的相关文章

Golang Slice 总结

数组 Go的切片是在数组之上的抽象数据类型,因此在了解切片之前必须要要理解数组.数组类型由指定和长度和元素类型定义.数组不需要显式的初始化:数组元素会自动初始化为零值:Go的数组是值语义.一个数组变量表示整个数组,它不是指向第一个元素的指针(比如C语言的数组).当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组.(为了避免复制数组,你可以传递一个指向数组的指针,但是数组指针并不是数组.)可以将数组看作一个特殊的struct,结构的字段名对应数组的索引,同时成员的数目固定. 切片 数组虽然

golang slice性能分析

golang在gc这块的做得比较弱,频繁地申请和释放内存会消耗很多的资源.另外slice使用数组实现,有一个容量和长度的问题,当slice的容量用完再继续添加元素时需要扩容,而这个扩容会把申请新的空间,把老的内容复制到新的空间,这是一个非常耗时的操作.有两种方式可以减少这个问题带来的性能开销: 在slice初始化的时候设置capacity(但更多的时候我们可能并不知道capacity的大小) 复用slice 下面就针对这两个优化设计了如下的benchmark,代码在: https://githu

Golang 入门 : 切片(slice)

切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概念构建的,可以按需自动增长和缩小.切片的动态增长是通过内置函数 append() 来实现的,这个函数可以快速且高效地增长切片,也可以通过对切片再次切割,缩小一个切片的大小.因为切片的底层也是在连续的内存块中分配的,所以切片还能获得索引.迭代以及为垃圾回收优化的好处.本文将介绍 Golang 切片的基本概念和用法,演示环境为 ubuntu 18.04 & go1.10.1. 切

Golang数据类型 切片(slice)

前言 Go中的数组数据类型的长度在声明的时候就已经固定了,切片是基于数组实现的 可变长度的容器. 切片的定义和初始化 切片类型和数组类型一样,想要使用,就必须要定义和初始化,不同之处已经提到,切片不需要指定切片的长度. 1.自定义切片 package main import ( "fmt" ) func main() { //切片的定义 var s1 []int //存放元素不限定,仅限定数据类型 var s2 []string fmt.Println(s1 == nil) //在初始

【转】 golang slice array

1. array   同一类型数据的集合     var arr [n]type    //声明type类型一维数组     var arr [m][n]type //声明type类型二维数组     多维数组以此类推     也可以用 := 声明     arr := [n]type{元素1[,元素2, ...]} 其中n可以用 "..." 三个点表示,系统会根据元素个数来确定   下标只能为 int 类型,而 php 还支持 string 类型的下标   1.1 数组长度 len(

golang slice

golang 在for range一个slice时,会读出其cap长度.在for的过程中,即使动态append该slice,最终for也会在第一次读取的cap长度处停止. package main import ( "fmt" ) func main() { s := make([]string, 3) s[0]="a" s[1]="b" s[2]="c" for _,i := range s { s = append(s,

slice切片函数

clc;clear all;close all; [X,Y,Z,V] = flow;x1 = min(min(min(X)));x2 = max(max(max(X)));y1 = min(min(min(Y)));y2 = max(max(max(Y)));z1 = min(min(min(Z)));z2 = max(max(max(Z)));sx = linspace(x1 + 1.3,x2,5);%五个垂直x面的切片;sy = 0;sz = 0;slice(X,Y,Z,V,sx,sy,sz

golang slice去重

golang内没有类似python中集合的数据结构,所以去重这样的运算只能自己造轮子了. 随手写了两个示例,一个是string类型的,一个是int类型的 package main import "fmt" func main() { s1 := []string{"111", "aaa", "bbb", "ccc", "aaa", "ddd", "ccc&q

Golang 数组 切片 字典 基本知识点

数组 数组的声明 var arrayName [arraySize]dataType eg: var array1 [5]int 在声明数组时,必须指定数组名,数组长度和数组元素的类型. 数组的初始化 当数组定义好以后,如果没有给数组元素指定值,则所有元素被自动初始化为类型所对应的零值 var array1 [5]int // [0 0 0 0 0] 变量的类型零值 在Go语言中,当一个变量被定义为某一种类型后,Go语言会自动初始化其值为零(Zero Value) 零值并不等于空值,而是当变量被