首页 > 其他分享 >Go语言中切片和数组有什么区别

Go语言中切片和数组有什么区别

时间:2023-11-10 17:07:30浏览次数:47  
标签:元素 切片 数组 Go 长度 array 底层

在Go语言中,数组的结构非常简单,它由两个部分组成:

  1. 数据类型(Data Type):数组中包含的元素的数据类型是固定的,所有元素必须具有相同的数据类型。这意味着一个数组可以包含整数、浮点数、字符串或其他数据类型,但所有元素的类型必须一致。
  2. 长度(Length):数组的长度是在声明时指定的,它表示数组中包含的元素数量。长度是数组类型的一部分,因此不同长度的数组被视为不同的类型。这也是Go数组的大小是固定的主要原因。

数组的结构示例:

var arr [5]int

在上面的示例中,我们声明了一个包含5个整数的数组。这个数组的数据类型是int,长度是5。每个元素都可以通过索引来访问,索引从0开始,最大为4(因为长度为5)。

需要注意的是,数组在Go中是值类型,这意味着当你将一个数组传递给函数或赋值给另一个数组时,实际上是复制整个数组的内容,而不是传递引用。这可能导致性能开销,特别是对于大型数组。因此,在需要处理动态大小数据集时,通常会使用切片(Slice)而不是数组。切片是对数组的引用,并提供了更灵活的长度和容量管理。

在Go语言中切片的底层结构是由一个结构体组成,结构体中有三个属性:

type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}
  1. 指向底层数组的指针(Pointer):切片包含一个指针,它指向底层的数组的第一个元素。这个指针用于定位切片在底层数组中的起始位置。
  2. 切片的长度(Length):切片的长度表示它包含的元素数量,也就是切片的大小。你可以使用内置的len()函数来获取切片的长度。
  3. 切片的容量(Capacity):切片的容量是指底层数组中从切片的起始位置到数组末尾的元素数量。它表示了切片可以增长的最大限度。你可以使用内置的cap()函数来获取切片的容量。

这三个部分一起构成了切片的底层结构,使切片成为一个灵活的数据结构,可以根据需要引用数组的一部分元素,并且可以动态调整长度和容量。这种底层结构的使用方式使得切片非常高效,因为它们与底层数组共享相同的存储,而不需要复制整个数据集。

下面是一个示例,演示了切片的底层结构:

package main

import "fmt"

func main() {
    // 创建一个数组
    arr := [5]int{1, 2, 3, 4, 5}

    // 创建一个切片,引用数组的一部分元素
    slice := arr[1:4]

    // 输出切片的长度和容量
    fmt.Printf("切片长度:%d,容量:%d\n", len(slice), cap(slice))
}

在上面的示例中,slice引用了数组arr的第2到第4个元素,因此它的长度为3,容量为4,因为底层数组从第2个元素开始还有4个元素。这个示例展示了切片底层结构的三个重要部分。

两则之间的区别

Go语言中切片(slice)和数组(array)是两种不同的数据结构,它们在用法和行为上有一些重要区别。

  1. 长度:
  • 数组(Array)的长度是固定的,定义时需要指定数组的长度,并且无法更改。例如,var arr [5]int 创建一个包含5个整数的数组,不能添加或删除元素。
  • 切片(Slice)的长度是可变的,它是对底层数组的一个动态窗口。切片可以根据需要增长或缩小。切片的长度可以使用内置的len()函数来获取。
  1. 内存管理:
  • 数组在创建时分配固定大小的内存空间,并且在整个生命周期内保持不变。
  • 切片在创建时不分配内存空间,而是引用一个已存在的数组。当切片长度增加时,它可能需要分配更多的内存,但这一过程是自动完成的。
  1. 传递和赋值:
  • 当你将一个数组传递给函数或赋值给另一个变量时,实际上是复制整个数组的值。这可能会导致性能问题,特别是对于大数组。
  • 切片是引用类型,传递或赋值切片时,实际上是传递了一个指向底层数组的引用。这意味着切片的操作不会复制整个数据集,更加高效。
// 数组传值
func main() {
 array := [3]string{"张三", "李四", "王五"}
 show1(array)
 fmt.Println("原数组", array)
}

func show1(array [3]string) {
 array[1] = "张三1"
 fmt.Println("修改后", array)
}
// 打印结果
修改后 [张三 张三1 王五]
原数组 [张三 李四 王五]
// 切片传值
func main() {
 array := []string{"张三", "李四", "王五"}
 show1(array)
 fmt.Println("原数组", array)
}

func show1(array []string) {
 array[1] = "张三1"
 fmt.Println("修改后", array)
}
// 打印结果
修改后 [张三 张三1 王五]
原数组 [张三 张三1 王五]
  1. 功能和用法:
  • 数组通常用于存储固定数量的元素,例如,表示一个日期的年、月、日等。
  • 切片常用于处理动态大小的数据集,可以方便地添加、删除和修改元素。它们类似于其他编程语言中的动态数组或列表。

标签:元素,切片,数组,Go,长度,array,底层
From: https://blog.51cto.com/u_10992108/8304656

相关文章

  • 设计模式 - Immutable 模式(Java不变集合类 vs Google Guava不变集合类)
    总结JDK中的unmodifiableList的构造函数是对原始集合的浅拷贝,而Guava.ImmutableList.copyOf是对原始集合的深拷贝 publicclassImmutableDemo{publicstaticvoidmain(String[]args){List<String>originalList=newArrayList<>();originalList.add("a"......
  • 已知数组arr = [2,20,3,12,9],现在要对数组进行遍历,只要数组存在大于10的元素,则输出tru
    Avarres=arr.filter((val1,val2)=>{returnval1>10;})console.log(res);Bvarres=arr.some((val1,val2)=>{returnval1>10;})console.log(res);Cvarres=arr.every((val1,val2)=>{returnval1>10;})console.log(res);Dvarres......
  • Golang使用nats
    nats自行安装packagemainimport( "fmt" "github.com/nats-io/nats.go")////nats-server在管理subject的时候是通过’.’进行分割的,server底层是使用treemodule分层管理subject.此处有两个通配符*和>。////*可以匹配以.分割的一切。如:////nc.Subscribe("aa.*......
  • 使用sizeof()和strlen()去计算【数组】和【指针】的大小
    (目录)一、知识回顾1、回顾sizeof()、strlen的作用:sizeof()是用来求取变量或者类型所占内存空间的大小(单位:字节)。sizeof计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么。sizeof不是函数,是操作符strlen()是一个库函数是专门用来计算字符串长度的,在......
  • 数组&队列&关联数组的总结
    定宽数组:可以直接赋值,也可以先声明再赋值其中还有多维数组intarray2[0:7][0:3];intarray3[8][4];//先个后位intascend[4]='{0,1,2,3};intdescend[5];descend='{4,3,2,1,0};descend[0:2]='{5,6,7};ascend='{4{8}};descend='{9,8,default:-1};数组的声明全在左......
  • mongodb等号格式的配置文件转换成yaml格式的配置文件
    环境:mongodb:4.4.22 1.等号格式的配置文件[root@localhostconf]#moremongo.cnfport=28001fork=truedbpath=/home/middle/mongodb/datalogpath=/home/middle/mongodb/log/mongodb.logpidfilepath=/home/middle/mongodb/run/28001.pidlogappend=truebind_ip=192.1......
  • 深层次分析字符数组和字符串的区别是什么?
    前言(1)休闲时刻刷B站,看到一个卖课的,发视频问,chararr1[]={‘H’,‘E’,‘L’,‘L’,‘O’};和chararr2[]=“HELLO”;区别是什么。(2)看那个卖课博主一顿分析,最后成功得出:字符串比字符数组末尾多一个’\0’。(3)很好,成功浪费我生命的3分钟。无语,就这水平还卖课。如果各位有幸看到这货,......
  • 剑指 Offer 66. 构建乘积数组
    文章目录题目描述思路分析完整代码题目描述给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B[i]的值是数组A中除了下标i以外的元素的积,即B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。思路分析将所有的数都乘起来得到一个总乘积,然后求......
  • Golang struct 结构体注意事项和使用细节
    结构体所有字段在内存当中是连续的typePointstruct{ x,yint}typeRectstruct{ leftUp,rightDownPoint}funcmain(){ //r1会在内存当中有四个整数 r1:=Rect{ leftUp:Point{ x:1, y:2, }, rightDown:Point{ x:3, y:4, }, } //r1有......
  • matlab将数组值划分为两类
    例如:大于0的处理为1,小于0的处理为-1.当然,可以选择循环结构和选择结构,但是效率会很低。这里直接使用逻辑语句完成。%不使用循环语句,将数组内值划分为两类clc;clearvars;a=[-0.1422,-0.0433,0.1131,0.0583,0.0109,-0.0863,0.0411,-0.0641,-0.1055,......