zoukankan      html  css  js  c++  java
  • Go语言基础之数组切片

    Go语言基础之数组切片

    目录:

    概述

    基于数组,数组切片天界了一系列管理功能,可以随时动态扩充存放空间,并且可以随意传递而不会导致所管理的元素被重复复制。

    数组切片的数据结构可以抽象为以下3个变量:

    • 一个指向原生数组的指针
    • 数组切片中的元素个数
    • 数组切片已分配的存储空间

    创建数组切片

    创建数组切片的方法主要有两种:

    基于数组

    数组切片可以基于一个已存在的数组创建,数组切片可以只使用数组的一部分元素或者整个数组来创建。

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        var array1 = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
        var arraySlice = array1[:5]
        fmt.Println("elements of array1:")
        for _, v := range array1 {
            fmt.Print(v, " ")
        }
        fmt.Println("
    elements of arraySlice:")
        for _, v := range arraySlice {
            fmt.Print(v, " ")
        }
    }
    

    通过数组的下标范围,创建切片

    直接创建

    通过内置函数make()可以灵活的创建数组切片。

    mySlice := make([]int, 5)           //创建一个初始元素为5的数组切片,元素的初始值为0,
    mySlice1 := make([]int, 5, 10)      //创建一个初始元素为5的数组切片,元素的初始值为0,并预留10个元素的存储空间
    mySlice2 := []int{1, 2, 3, 4, 5}     //直接创建并初始化包含5个元素的数组切片。
    

    元素遍历

    操作数组元素的所有方法都适用于数组切片,数组切片也可以按下标读写元素,用len()函数操作元素个数,支持使用range关键字快速遍历所有元素。

    
    

    动态增减元素

    可动态增减元素个数是数组切片比数组更为强大的功能。与数组相比,数组切片多了一个存储能力(capacity)的概念,即元素个数和分配空间可以是两个不同的值。合理的设置存储能力的值,可以大幅降低数组切片内部重新分配内存块的频率,从而大大提高程序的性能。

    数组切片支持GO语言内置的cap()len()函数,cap()函数返回的是数组切片分配的空间大小,len()函数返回的是数组切片中当前所存储的元素个数。

    package main
    
    import "fmt"
    
    func main() {
        slice1 := make([]int, 5, 10)
    
        fmt.Println("len(slice1):", len(slice1))
        fmt.Println("cap(slice1):", cap(slice1))
    }
    // len(slice1): 5
    // cap(slice1): 10
    

    数组切片通过append()函数添加元素,其中,第二个参数是一个不定参数,可根据需求添加如干个元素。甚至可以直接将一个数组切片追加到一个数组切片的末尾

    slice1 = append(slice1, 1, 2, 3, 4)
    slice2 := []int{8, 9}
    slice1 = append(slice1, slice2...)
    

    需要注意的是slice2...中的...,如果没有这个省略号,则会编译报错,这里的左右就是将slice2包含的所有元素打散后传入slice1

    数组切片会自动处理存储空间不足的问题。可以通过查看$GOROOT/src/runtime/slice.go源码,其中扩容相关代码如下:

    newcap := old.cap
    doublecap := newcap + newcap
    if cap > doublecap {
        newcap = cap
    } else {
        if old.len < 1024 {
            newcap = doublecap
        } else {
            // Check 0 < newcap to detect overflow
            // and prevent an infinite loop.
            for 0 < newcap && newcap < cap {
                newcap += newcap / 4
            }
            // Set newcap to the requested cap when
            // the newcap calculation overflowed.
            if newcap <= 0 {
                newcap = cap
            }
        }
    }
    

    基于数组切片创建数组切片

    类似于数组切片可以基于一个数组创建,数组切片也可以基于另一个数组切片创建。

    oldSlice := []int{1, 2, 3, 4, 5}
    newSlice := oldSlice[:3]
    

    其中,选择oldSlice的元素范围可以超过所以包含的元素个数,但是不能超过oldSlice的存储能力(cap()返回的值),超出oldSlice元素的个数部分会使用0补充。

    内容复制

    通过内置函数copy(),将内容从一个数组切片复制到另一个数组切片。如果两个数组切片不一样大,则会按照较小的数组切片的元素个数进行复制。

    slice1 := []int{1, 2, 3, 4, 5}
    slice2 := []int{5, 4, 3}
    cpoy(slice2, slice1)     //只会将slice1的前三个元素复制到slice2中
    cpoy(slice1, slice2)     //只会将slice2的三个元素复制到slice1的前三个位置
    
  • 相关阅读:
    LeetCode:230. 二叉搜索树中第K小的元素
    LeetCode:229. 求众数 II
    LeetCode:228. 汇总区间
    LeetCode:225. 用队列实现栈
    LeetCode:209. 长度最小的子数组
    LeetCode:208. 实现 Trie (前缀树)
    疯狂的订餐系统-软件需求分析挑战之旅 【转】
    产品需求文档(PRD)的写作 【转】
    软件需求文档标准格式
    通过实例编写开发规范文档 【转】
  • 原文地址:https://www.cnblogs.com/linga/p/12494712.html
Copyright © 2011-2022 走看看