为什么在Go中有数组? [英] Why have arrays in Go?

查看:100
本文介绍了为什么在Go中有数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我明白Go中数组和片的区别。但是我不明白的是为什么数组完全有帮助。为什么数组类型定义指定长度和元素类型会有帮助?为什么我们使用的每个数组都不是一个分片? ://golang.org/ref/spec#Array_typesrel =nofollow noreferrer>数组,而不仅仅是固定长度: 可比 ,它们是(不是引用或指针类型)。

在某些情况下,数组相对于数组具有无数的优点,所有这些优点都超过了证明数组存在(与切片一起)的理由。我们来看看他们。 (我甚至没有把数组当作片的构建块)。






1。可比较意味着你可以在地图中使用数组作为键,但不能使用切片。是的,你现在可以说,为什么不让切片与之相当,所以单凭这一点就不能证明两者的存在。平等在切片上没有很好的定义。 常见问题:为什么地图不允许切片作为关键字?


它们不实现相等性,因为在这些类型上没有很好地定义相等性;有很多考虑因素涉及浅层比较深度比较,指针与值比较,如何处理递归类型等。


2。 数组也可以为您提供更高的编译时安全性,因为可以在编译时检查索引边界(数组长度必须评估为非负数常量可由类型 int 的值表示) :

  s:= make([] int,3)
s [3] = 3 //Only运行时错误:运行时错误:索引超出范围

a:= [3] int {}
a [3] = 3 //编译时错误:数组索引3无效3元素数组的限制)

3。 传递围绕或分配数组值将隐式地创建整个数组的一个副本,所以它将与原始值分离。如果传递一个片段,它仍然会创建一个副本,但只是片段头部,但片段值(头部)将指向相同的支持数组。这可能是也可能不是你想要的。如果你想从原始中分离切片,你必须明确地复制内容,例如内置 copy() 函数到一个新的切片。

  a:= [2] int {1,2} 
b:= a
b [0] = 10 //这只影响b,a将保持{1,2}

sa:= [] int {1,2,$}
sb:= sa
sb [0] = 10 //影响sb和​​sa

4 。另外,由于数组长度是数组类型的一部分,因此不同长度的数组是不同类型的。一方面,这可能是一个痛苦的屁股(例如,你写一个函数,它的参数类型为 [4] int ),你不能使用该函数以获取和处理 [5] int 类型的数组),但这也可能是一个优点:这可能用于显式指定长度预期的阵列。例如。你想写一个需要IPv4地址的函数,它可以用 [4] byte 类型建模。现在你有一个编译时间的保证,传递给你的函数的值将有正好4个字节,不多也不少(这将是一个无效的IPv4地址)。



5。与前面的内容相关,数组长度也可用于文档目的。类型 [4]字节恰当地表明IPv4有4个字节。 [3] byte 类型的 rgb 变量告诉每个颜色分量有1个字节。在某些情况下,它甚至被取出并可用,分开记录;例如在 crypto / md5 包: md5.Sum() 返回一个类型为 [Size] byte 的值,其中 md5.Size 是一个常量< 16 :MD5校验和的长度。



6。 strong>规划内存布局的结构类型,请参阅JimB的答案,并这个答案更详细和真实的例子



7。另外,由于切片是标题,它们(几乎)总是按原样传递(无指针) 语言规范对指向切片的指针比指向数组的指针更严格。例如,该规范提供了用于指向数组的操作的多个shorthands,而在切片的情况下,这给出了编译时错误(因为很少使用指向slice的指针,如果您仍然需要/必须这样做,您必须明确的处理它;阅读更多在这个答案)。



这样的例子是:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆