go6---slice切片

简介:
复制代码
package main

/*
切片Slice
其本身并不是数组,它指向底层的数组
作为变长数组的替代方案,可以关联底层数组的局部或全部
为引用类型
可以直接创建或从底层数组获取生成
使用len()获取元素个数,cap()获取容量
一般使用make()创建
如果多个slice指向相同底层数组,其中一个的值改变会影响全部
make([]T, len, cap)
其中cap可以省略,则和len的值相同
len表示存数的元素个数,cap表示容量

用new创建数组的时候是一个指向数组的指针。
*/

import (
    "fmt"
)

func main() {
    var slice1 []int //中括号里面是数字或者3个点就表示数组,
    //中括号里面既不是数字也不是3个点就表示是slice不是数组
    fmt.Println(slice1) //[],slice的底层也是数组保存的,打印也是数组的格式,

    a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println(a) //[1 2 3 4 5 6 7 8 9 0]

    s1 := a[2]      //一个slice
    fmt.Println(s1) //3

    s2 := a[5:10]   //数组的索引从5到9,包头不包尾,//一个slice
    fmt.Println(s2) //[6 7 8 9 0]

    s3 := a[5:len(a)] //数组的索引从5到长度减一,包头不包尾,//一个slice
    fmt.Println(s3)   //[6 7 8 9 0]

    s4 := a[5:]     //数组的索引从5到尾部,//一个slice
    fmt.Println(s4) //[6 7 8 9 0]

    s5 := a[:5]     //数组的索引从开头到索引为4,//一个slice
    fmt.Println(s5) //[1 2 3 4 5]

    s11 := make([]int, 3) //初始化3个元素,并放在slice所指向的数组中,
    fmt.Println(s11)      //    [0 0 0]

    s22 := make([]int, 3, 10) //初始化3个元素,slice指向的是一个数组,数组是一块连续的内存,
    //数组不能动态修改长度, 10第三个参数是数组的容量,现在是3个,但是总共可以有10个,当超出10个后
    //会重新分配连续的内存块(内存地址改变了)(重新分配内存的效率低),并且容量扩大一倍成20,
    fmt.Println(s22)                //    [0 0 0]
    fmt.Println(len(s22), cap(s22)) //    3,10

    //slice是引用类型的并且可以扩容的数组

    a1 := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}
    s33 := a1[2:5]           //一个slice
    fmt.Println(s33)         //    [99 100 101]
    fmt.Println(string(s33)) //    cde

    /*
        Reslice
        Reslice时索引以被slice的切片为准
        索引不可以超过被slice的切片的容量cap()值
        索引越界不会导致底层数组的重新分配而是引发错误
    */
    //从slice中获取slice
    s44 := s33[1:3]          //一个slice
    fmt.Println(s44)         //[100 101]
    fmt.Println(string(s44)) //de

    /*
        Append
        可以在slice尾部追加元素
        可以将一个slice追加在另一个slice尾部
        如果最终长度未超过追加到slice的容量则返回原始slice
        如果超过追加到的slice的容量则将重新分配数组并拷贝原始数据
    */

    s55 := make([]int, 3, 6)        //3个元素容量为6的slice
    fmt.Printf("%v,%p\n", s55, s55) //[0 0 0],0xc04200e2a0
    s55 = append(s55, 1, 2, 3)
    fmt.Printf("%v,%p\n", s55, s55) //[0 0 0 1 2 3],0xc04200e2a0,没有超过容量不重新分配内存地址
    s55 = append(s55, 1, 2, 3)
    fmt.Printf("%v,%p\n", s55, s55) //[0 0 0 1 2 3 1 2 3],0xc04203a120,超过容量重新分配内存地址

    a2 := [...]int{1, 2, 3, 4, 5}
    s66 := a2[2:5] //[3 4 5],不显示的加容量,则容量就是此时slice中元素的个数3,
    s77 := a2[1:3] // [2 3]
    fmt.Println(s66, s77)
    s66[0] = 9
    fmt.Println(s66, s77) //[9 4 5] [2 9],slice指向一个底层的数组,其中一个改变另外一个也改变,
    //如果超过slice的容量会重新分配内存,此时改变这个slice其他的slice就不会改变了
    s66 = append(s66, 1, 2, 3, 2, 3, 2, 3, 4, 3, 4)
    s66[0] = 99
    fmt.Println(s66, s77) //[99 4 5 1 2 3 2 3 2 3 4 3 4] [2 9]

    //slice的copy函数
    s88 := []int{1, 2, 3, 4, 5, 6}
    s99 := []int{7, 8, 9}
    copy(s88, s99)        //左边是拷贝到的元素,后面是被拷贝的元素,吧前三个元素拷贝到s88的前三个
    fmt.Println(s88, s99) //[7 8 9 4 5 6] [7 8 9]

    ss11 := []int{1, 2, 3, 4, 5, 6}
    ss22 := []int{7, 8, 9}
    copy(ss22, ss11)
    fmt.Println(ss11, ss22) //[1 2 3 4 5 6] [1 2 3],ss22只有3个元素,则只接收3个元素逇拷贝

    ss33 := []int{1, 2, 3, 4, 5, 6}
    ss44 := []int{7, 8, 9}
    copy(ss33, ss44[1:2])      //部分拷贝
    copy(ss33[2:4], ss44[1:2]) //指定拷贝到哪里
    fmt.Println(ss33, ss44)    //[1 2 3 4 5 6] [1 2 3],ss22只有3个元素,则只接收3个元素逇拷贝

}
复制代码

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/8072353.html,如需转载请自行联系原作者

相关文章
|
3月前
|
存储 JSON 安全
Go语言切片,使用技巧与避坑指南
Go语言中的切片(Slice)是动态引用数组的高效数据结构,支持扩容与截取。本文从切片基础、常用操作到高级技巧全面解析,涵盖创建方式、`append`扩容机制、共享陷阱及安全复制等内容。通过代码示例详解切片特性,如预分配优化性能、区分`nil`与空切片、处理多维切片等。掌握这些核心知识点,可编写更高效的Go代码。
155 2
|
2月前
|
数据采集 机器学习/深度学习 存储
Go语言实战案例 - 找出切片中的最大值与最小值
本案例通过实现查找整数切片中的最大值与最小值,帮助初学者掌握遍历、比较和错误处理技巧,内容涵盖算法基础、应用场景及完整代码示例,适合初学者提升编程能力。
|
3月前
|
Go 索引
Go语言中使用切片需要注意什么?
本文详细讲解了Go语言中切片(Slice)的使用方法与注意事项。切片是对数组连续片段的引用,具有灵活的操作方式。文章从定义与初始化、长度与容量、自动扩容、共享底层数组、复制、边界检查、零值到拼接等方面展开,并配以示例代码演示。通过学习,读者可深入了解切片的工作原理及优化技巧,避免常见陷阱,提升编程效率与代码质量。
107 2
|
4月前
|
安全 Go 开发者
Go语言之切片的原理与用法 - 《Go语言实战指南》
切片(slice)是Go语言中用于处理变长数据集合的核心结构,基于数组的轻量级抽象,具有灵活高效的特点。切片本质是一个三元组:指向底层数组的指针、长度(len)和容量(cap)。本文详细介绍了切片的声明与初始化方式、基本操作(如访问、修改、遍历)、长度与容量的区别、自动扩容机制、共享与副本处理、引用类型特性以及常见陷阱。通过理解切片的底层原理,开发者可以更高效地使用这一数据结构,优化代码性能。
111 13
|
9月前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
177 7
|
7月前
|
测试技术 Go API
Go 切片导致 rand.Shuffle 产生重复数据的原因与解决方案
在 Go 语言开发中,使用切片时由于其底层数据共享特性,可能会引发意想不到的 Bug。本文分析了 `rand.Shuffle` 后切片数据重复的问题,指出原因在于切片是引用类型,直接赋值会导致底层数组共享,进而影响原始数据。解决方案是使用 `append` 进行数据拷贝,确保独立副本,避免 `rand.Shuffle` 影响原始数据。总结强调了切片作为引用类型的特性及正确处理方法,确保代码稳定性和正确性。
195 82
|
10月前
|
Go 索引
Go语言中,遍历数组或切片
在Go语言中,遍历数组或切片
193 6
|
4月前
|
人工智能 Go
[go]Slice 切片原理
本文详细介绍了Go语言中的切片(slice)数据结构,包括其定义、创建方式、扩容机制及常见操作。切片是一种动态数组,依托底层数组实现,具有灵活的扩容和传递特性。文章解析了切片的内部结构(包含指向底层数组的指针、长度和容量),并探讨了通过`make`创建切片、基于数组生成切片以及切片扩容的规则。此外,还分析了`append`函数的工作原理及其可能引发的扩容问题,以及切片拷贝时需要注意的细节。最后,通过典型面试题深入讲解了切片在函数间传递时的行为特点,帮助读者更好地理解和使用Go语言中的切片。
102 0
|
7月前
|
存储 Go
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
173 3
Go 语言入门指南:切片
|
9月前
|
Go 索引
go语言for遍历数组或切片
go语言for遍历数组或切片
283 62